Análise do Jogo de Imagens aplicadas no Ensino médio

Amostra dos dados da pesquisa realizada

Tabulação do número de acertos dos itens do jogo de imagens.

Coluna Descrição
Exoticas Número de acertos dentre todas as imagens exibidas do tipo exótica, valor experado é 5.
Nativas Número de acertos dentre todas as imagens exibidas do tipo nativa, valor experado é 5.
head(pos_gabarito$dados, 10)

Determinado a taxa de percepção

Entende-se por taxa de percepção o fator determinado pela quantidade média de acertos dentre as questões apresentadas aos alunos, em relação a turma em que o questionario foi aplicado.

Percepção dos alunos

print(pos_gabarito$percentual_acerto)

Entendendo a distribuição das médias

Níveis de reconhecimento (acertos) por tipo de origem dos animais

grid.arrange(
    plotAnaliseMedias(pos_gabarito$percentual_acerto$p_nome_exoticas,
                  pos_gabarito$percentual_acerto$p_nome_nativas,
                  "Identificação dos nomes"),
    plotAnaliseMedias(pos_gabarito$percentual_acerto$p_origem_exoticas,
                  pos_gabarito$percentual_acerto$p_origem_nativas,
                  "Identificação das origens", y = ""),
    plotAnaliseMedias(pos_gabarito$percentual_acerto$p_indice_exoticas,
                  pos_gabarito$percentual_acerto$p_indice_nativas,
                  "Taxa de reconhecimento", y = ""), 
    ncol = 3,
    top = textGrob("Niveis de reconhecimento por origem\n", 
                   gp = gpar(fontsize = 20, font = 2)),
    right = "\n"
)

Diferença de acertos

grid.arrange(
    ggplot(pos_gabarito$dados, aes(exoticas - nativas)) +
        geom_histogram(bins = 9) +
        labs(title = "Identificação dos nomes", y = "Total de acertos") +
        my_theme,
    ggplot(pos_gabarito$dados, aes(origem_exoticas - origem_nativas)) +
        geom_histogram(bins = 9) +
        labs(title = "Identificação das origens", y = "") +
        my_theme,
    ggplot(pos_gabarito$dados, aes(indice_exoticas - indice_nativas)) +
        geom_histogram(bins = 9) +
        labs(title = "Taxa de reconhecimento", y = "") +
        my_theme, 
    ggtexttable(normalidade(pos_gabarito$dados$exoticas - pos_gabarito$dados$nativas),
                rows = NULL, theme = ttheme(base_style = "mOrange", base_size = 9)),
    ggtexttable(normalidade(pos_gabarito$dados$origem_exoticas - pos_gabarito$dados$origem_nativas),
                rows = NULL, theme = ttheme(base_style = "mOrange", base_size = 9)),
    ggtexttable(normalidade(pos_gabarito$dados$indice_exoticas - pos_gabarito$dados$indice_nativas),
                rows = NULL, theme = ttheme(base_style = "mOrange", base_size = 9)),
    ncol = 3,
    top = textGrob("Histograma das diferenças Exoticas x Nativas\n", 
                   gp = gpar(fontsize = 20, font = 2)),
    heights=c(3/4, 1/4),
    right = "\n",
    bottom = "\n"
)

Grupos taxonómicos

grid.arrange(
    plotAnaliseMedias(pos_gabarito$percentual_acerto$p_exotica_aves,
                  pos_gabarito$percentual_acerto$p_nativa_aves,
                  "Aves"),
    plotAnaliseMedias(pos_gabarito$percentual_acerto$p_exotica_invertebrado,
                  pos_gabarito$percentual_acerto$p_nativa_invertebrado,
                  "Invertebrados", y = ""),
    plotAnaliseMedias(pos_gabarito$percentual_acerto$p_exotica_mamifero,
                  pos_gabarito$percentual_acerto$p_nativa_mamifero,
                  "Mamiferos", y = ""), 
    plotAnaliseMedias(pos_gabarito$percentual_acerto$p_exotica_peixe,
                  pos_gabarito$percentual_acerto$p_nativa_peixe,
                  "Mamiferos", y = ""), 
    plotAnaliseMedias(pos_gabarito$percentual_acerto$p_exotica_reptil,
                  pos_gabarito$percentual_acerto$p_nativa_reptil,
                  "Répteis", y = ""), 
    ncol = 5,
    top = textGrob("Niveis de reconhecimento por origem\n", 
                   gp = gpar(fontsize = 20, font = 2)),
    right = "\n"
)

Medindo as médias de acerto na identificação do nome das espécies

barplot(tapply(
    pos_gabarito$percentual_acerto$p_indice_exoticas, 
    pos_gabarito$percentual_acerto$turmas,
    mean), main = "Média de identificação do nome de origem exóticas por turmas")

barplot(tapply(
    pos_gabarito$percentual_acerto$p_indice_nativas, 
    pos_gabarito$percentual_acerto$turmas,
    mean), main = "Média de identificação do nome de origem nativas por turmas")

Teste de normalidade

Para determinar a normalidade nas distribuiçoes das respostas do jogo de imagens.

Identificação médio das turmas (nomes das espécies & origens)

grid.arrange(t1$plot, t2$plot,
             t1$normalidade, t2$normalidade,
             t3$plot, t4$plot,
             t3$normalidade, t4$normalidade,
             ncol = 2,
             heights = c(3,2,3,2),
             top = textGrob("Densidade de identificação média das turmas entre \nespecies e suas origens\n",
                            gp = gpar(fontsize = 20, font = 2))
             )

Indice de reconhecimento médio das turmas

grid.arrange(t5$plot, t6$plot,
             t5$normalidade, t6$normalidade,
             ncol = 2,
             heights = c(4,3),
             top = textGrob("Densidade dos indices de reconhecimento médio das turmas\n",
                            gp = gpar(fontsize = 20, font = 2))
             )

Q-Q Test

qqplot.data <- function (vec, titulo) {
  # following four lines from base R's qqline()
  y <- quantile(vec[!is.na(vec)], c(0.25, 0.75))
  x <- qnorm(c(0.25, 0.75))
  slope <- diff(y)/diff(x)
  int <- y[1L] - slope * x[1L]
  d <- data.frame(resids = vec)
  ggplot(d, aes(sample = resids)) + 
      stat_qq() + 
      geom_abline(slope = slope, intercept = int, col = "red") +
      xlim(-2, 2) +
      ylim(0, 1) +
      theme_bw() +
      labs(
        title = titulo
    )
}
q1 <- qqplot.data(pos_gabarito$proporcoes$por_turma$p_nativas, "Identificação do nome das espécies de origem Nativas")
q2 <- qqplot.data(pos_gabarito$proporcoes$por_turma$p_exoticas, "Identificação do nome das espécies de origem Exoticas")
q3 <- qqplot.data(pos_gabarito$proporcoes$por_turma$p_origem_nativas, "Identificação de origem Nativas")
q4 <- qqplot.data(pos_gabarito$proporcoes$por_turma$p_origem_exoticas, "Identificação de origem Exoticas")
q5 <- qqplot.data(pos_gabarito$proporcoes$por_turma$p_indice_nativas, "Indice de reconhecimento Nativas (origens + espécies)")
q6 <- qqplot.data(pos_gabarito$proporcoes$por_turma$p_indice_exoticas, "Indice de reconhecimento Exoticas (origens + espécies)")
grid.arrange(q1, q2, 
             q3, q4,
             q5, q6,
             ncol = 2,
             top = textGrob("Normal Q-Q Plot\n", 
                            gp = gpar(fontsize = 20, font = 2))
             )

Teste de variância

Para determinar a variância

variancia <- data.frame(
    Algoritmo = c("F test to compare two variances"),
    "Comparação" = c("Nativas x Exóticas"),
    "Variável" = c(
        "Indice de reconhecimento",
        "Identificação do nome das espécies",
        "Identificação da origem"
    ),
    "p_valor" = c(
        var.test(pos_gabarito$proporcoes$por_turma$p_indice_nativas, 
                 pos_gabarito$proporcoes$por_turma$p_indice_exoticas, 
                 alternative = "two.sided")$p.value,
        var.test(pos_gabarito$proporcoes$por_turma$p_nativas, 
                 pos_gabarito$proporcoes$por_turma$p_exoticas, 
                 alternative = "two.sided")$p.value,
        var.test(pos_gabarito$proporcoes$por_turma$p_origem_nativas, 
                 pos_gabarito$proporcoes$por_turma$p_origem_exoticas, 
                 alternative = "two.sided")$p.value
    )
)
variancia <- variancia %>%
    mutate(
        variancia = p_valor > 0.05,
        p_valor = cell_spec(round(p_valor, 4), bold = T, color = "black", align = "right"),
        variancia = cell_spec(variancia, bold = variancia,
                       color= ifelse(variancia, "white", "black"), 
                       background = ifelse(variancia, "green", "#CCCCCC"))
    )
variancia %>%
  kable(escape = F) %>%
  kable_styling(c("striped", "bordered"), full_width = TRUE) %>%
  column_spec(1, bold = TRUE) %>%
  collapse_rows(columns = 1:2, valign = "top") 
Algoritmo Comparação Variável p_valor variancia
F test to compare two variances Nativas x Exóticas Indice de reconhecimento 0.279 TRUE
Identificação do nome das espécies 0.6553 TRUE
Identificação da origem 0.0343 FALSE

Analises descritivas

head(pos_gabarito$especies, 10)

Indice de identificação por Origem

Indice de identificação por Espécie

Testes de hipoteses

Esperado p-valor >= 0.05 na normalidade (espera-se H0) Esperado p-valor <= 0.05 no teste de hipotese (espera-se H1)

Tabela dos testes de hipoteses aplicados

t1 <- t.test(
   pos_gabarito$percentual_acerto$p_nome_exoticas, 
   pos_gabarito$percentual_acerto$p_nome_nativas, 
   alternative = "two.sided", paired = TRUE, conf.level = .95)
t2 <- t.test(
   pos_gabarito$percentual_acerto$p_origem_exoticas, 
   pos_gabarito$percentual_acerto$p_origem_nativas, 
   alternative = "two.sided", paired = TRUE, conf.level = .95)
t3 <- t.test(
   pos_gabarito$percentual_acerto$p_indice_exoticas, 
   pos_gabarito$percentual_acerto$p_indice_nativas, 
   alternative = "two.sided", paired = TRUE, conf.level = .95)
data.frame(
    Algoritmo = c(t1$method, t2$method, t3$method),
    "Comparação" = c("Exóticas x Nativas"),
    "Variável" = c(
        "Identificação do nome das espécies",
        "Identificação da origem",
        "Indice de reconhecimento"
    ),
    p_valor = c(t1$p.value, t2$p.value, t3$p.value),
    H0 = c(t1$p.value >= 0.05, t2$p.value >= 0.05, t3$p.value >= 0.05),
    H1 = c(t1$p.value < 0.05, t2$p.value < 0.05, t3$p.value < 0.05),
    "Confiança" = c(
        paste(paste0(round(t1$conf.int * 100, 2), "%"), collapse = " ~ "),
        paste(paste0(round(t2$conf.int * 100, 2), "%"), collapse = " ~ "),
        paste(paste0(round(t3$conf.int * 100, 2), "%"), collapse = " ~ ")
    )
) %>%
  mutate(
    p_valor = cell_spec(p_valor, bold = T, color = "black", align = "right"),
    H0 = cell_spec(H0, bold = H0,
                   color= ifelse(H0, "white", "black"), 
                   background = ifelse(H0, "green", "#CCCCCC")),
    H1 = cell_spec(H1, bold = H1, 
                   color = ifelse(H1, "white", "black"), 
                   background = ifelse(H1, "green", "#CCCCCC"))
  ) %>%
  kable(escape = F) %>%
  kable_styling(c("striped", "bordered"), full_width = TRUE) %>%
  column_spec(1, bold = TRUE) %>%
  collapse_rows(columns = 1:2, valign = "top") %>%
  footnote(general = "Intervalo de confiança 95%",
           general_title = "\nObs.: ",
           footnote_as_chunk = T)
Algoritmo Comparação Variável p_valor H0 H1 Confiança
Paired t-test Exóticas x Nativas Identificação do nome das espécies 5.68550807349726e-89 FALSE TRUE 34.15% ~ 39.53%
Identificação da origem 9.53291446070658e-46 FALSE TRUE -31.12% ~ -24.46%
Indice de reconhecimento 2.02846120518247e-13 FALSE TRUE 8.58% ~ 14.53%

Obs.:
Intervalo de confiança 95%

1 - Os alunos itendificam mais os nomes dos animais de espécies exóticas que os animais de espécies nativas.


    Paired t-test

data:  pos_gabarito$percentual_acerto$p_nome_exoticas and pos_gabarito$percentual_acerto$p_nome_nativas
t = 27, df = 370, p-value <2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 0.3415 0.3953
sample estimates:
mean of the differences 
                 0.3684 

2 - Os alunos identificam mais espécies de origem exótica que as de origem nativa.


    Paired t-test

data:  pos_gabarito$percentual_acerto$p_origem_exoticas and pos_gabarito$percentual_acerto$p_origem_nativas
t = -16, df = 370, p-value <2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.3112 -0.2446
sample estimates:
mean of the differences 
                -0.2779 

3 - Os alunos identificam mais as espécies exóticas (nome dos animais e origem) que espécies nativas.


    Paired t-test

data:  pos_gabarito$percentual_acerto$p_indice_exoticas and pos_gabarito$percentual_acerto$p_indice_nativas
t = 7.6, df = 370, p-value = 2e-13
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 0.08576 0.14530
sample estimates:
mean of the differences 
                 0.1155 

4 - Os alunos reconhecem mais mamíferos do que os demais grupos taxonómicos.

pos_gabarito$taxonomicos %>%
    ggplot() + 
    geom_boxplot(aes(x = grupo, y = value, fill = origem), show.legend = T) + 
    scale_y_continuous(limits = c(0,1), labels = scales::percent) +
    theme_bw() +
    labs(title = "Boxplot de identificação de espécies por grupo taxonômico",
         y = "Percentual de identificação", x = "") +
    my_theme

tmp <- pos_gabarito$percentual_acerto %>%
    select(p_exotica_aves:p_nativa_reptil) %>%
    melt()
No id variables; using all as measure variables
tmp <- cbind(tmp, colsplit(tmp$variable, "_", c("p", "indicador", "origem"))) %>%
    select(indicador, origem, value)
anova(lm(value ~ indicador * origem, tmp))
Analysis of Variance Table

Response: value
                   Df Sum Sq Mean Sq F value  Pr(>F)    
indicador           1   31.1   31.13   608.4 < 2e-16 ***
origem              4    3.8    0.94    18.4 5.6e-15 ***
indicador:origem    4    4.6    1.14    22.3 < 2e-16 ***
Residuals        3660  187.3    0.05                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(aov(lm(value ~ indicador * origem, tmp)))
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = lm(value ~ indicador * origem, tmp))

$indicador
                  diff     lwr     upr p adj
nativa-exotica -0.1842 -0.1988 -0.1696     0

$origem
                            diff      lwr       upr  p adj
invertebrado-aves     -7.629e-02 -0.10852 -0.044070 0.0000
mamifero-aves         -2.498e-15 -0.03222  0.032225 1.0000
peixe-aves            -2.452e-02 -0.05675  0.007702 0.2303
reptil-aves           -6.471e-02 -0.09694 -0.032489 0.0000
mamifero-invertebrado  7.629e-02  0.04407  0.108519 0.0000
peixe-invertebrado     5.177e-02  0.01955  0.083996 0.0001
reptil-invertebrado    1.158e-02 -0.02064  0.043805 0.8640
peixe-mamifero        -2.452e-02 -0.05675  0.007702 0.2303
reptil-mamifero       -6.471e-02 -0.09694 -0.032489 0.0000
reptil-peixe          -4.019e-02 -0.07242 -0.007966 0.0060

$`indicador:origem`
                                              diff       lwr       upr  p adj
nativa:aves-exotica:aves                 -0.110354 -0.163216 -0.057493 0.0000
exotica:invertebrado-exotica:aves        -0.016349 -0.069210  0.036513 0.9934
nativa:invertebrado-exotica:aves         -0.246594 -0.299456 -0.193732 0.0000
exotica:mamifero-exotica:aves             0.051771 -0.001091  0.104633 0.0607
nativa:mamifero-exotica:aves             -0.162125 -0.214987 -0.109264 0.0000
exotica:peixe-exotica:aves                0.057221  0.004359  0.110082 0.0218
nativa:peixe-exotica:aves                -0.216621 -0.269483 -0.163760 0.0000
exotica:reptil-exotica:aves              -0.073569 -0.126431 -0.020708 0.0005
nativa:reptil-exotica:aves               -0.166213 -0.219074 -0.113351 0.0000
exotica:invertebrado-nativa:aves          0.094005  0.041144  0.146867 0.0000
nativa:invertebrado-nativa:aves          -0.136240 -0.189101 -0.083378 0.0000
exotica:mamifero-nativa:aves              0.162125  0.109264  0.214987 0.0000
nativa:mamifero-nativa:aves              -0.051771 -0.104633  0.001091 0.0607
exotica:peixe-nativa:aves                 0.167575  0.114713  0.220437 0.0000
nativa:peixe-nativa:aves                 -0.106267 -0.159129 -0.053405 0.0000
exotica:reptil-nativa:aves                0.036785 -0.016077  0.089646 0.4549
nativa:reptil-nativa:aves                -0.055858 -0.108720 -0.002997 0.0285
nativa:invertebrado-exotica:invertebrado -0.230245 -0.283107 -0.177384 0.0000
exotica:mamifero-exotica:invertebrado     0.068120  0.015258  0.120982 0.0019
nativa:mamifero-exotica:invertebrado     -0.145777 -0.198638 -0.092915 0.0000
exotica:peixe-exotica:invertebrado        0.073569  0.020708  0.126431 0.0005
nativa:peixe-exotica:invertebrado        -0.200272 -0.253134 -0.147411 0.0000
exotica:reptil-exotica:invertebrado      -0.057221 -0.110082 -0.004359 0.0218
nativa:reptil-exotica:invertebrado       -0.149864 -0.202725 -0.097002 0.0000
exotica:mamifero-nativa:invertebrado      0.298365  0.245503  0.351227 0.0000
nativa:mamifero-nativa:invertebrado       0.084469  0.031607  0.137330 0.0000
exotica:peixe-nativa:invertebrado         0.303815  0.250953  0.356676 0.0000
nativa:peixe-nativa:invertebrado          0.029973 -0.022889  0.082834 0.7387
exotica:reptil-nativa:invertebrado        0.173025  0.120163  0.225886 0.0000
nativa:reptil-nativa:invertebrado         0.080381  0.027520  0.133243 0.0001
nativa:mamifero-exotica:mamifero         -0.213896 -0.266758 -0.161035 0.0000
exotica:peixe-exotica:mamifero            0.005450 -0.047412  0.058311 1.0000
nativa:peixe-exotica:mamifero            -0.268392 -0.321254 -0.215531 0.0000
exotica:reptil-exotica:mamifero          -0.125341 -0.178202 -0.072479 0.0000
nativa:reptil-exotica:mamifero           -0.217984 -0.270845 -0.165122 0.0000
exotica:peixe-nativa:mamifero             0.219346  0.166484  0.272208 0.0000
nativa:peixe-nativa:mamifero             -0.054496 -0.107358 -0.001634 0.0370
exotica:reptil-nativa:mamifero            0.088556  0.035694  0.141418 0.0000
nativa:reptil-nativa:mamifero            -0.004087 -0.056949  0.048775 1.0000
nativa:peixe-exotica:peixe               -0.273842 -0.326704 -0.220980 0.0000
exotica:reptil-exotica:peixe             -0.130790 -0.183652 -0.077928 0.0000
nativa:reptil-exotica:peixe              -0.223433 -0.276295 -0.170572 0.0000
exotica:reptil-nativa:peixe               0.143052  0.090190  0.195913 0.0000
nativa:reptil-nativa:peixe                0.050409 -0.002453  0.103270 0.0766
nativa:reptil-exotica:reptil             -0.092643 -0.145505 -0.039781 0.0000
# Realizando Anova fatorial
anova(lm(value ~ grupo * origem, pos_gabarito$taxonomicos))
Analysis of Variance Table

Response: value
              Df Sum Sq Mean Sq F value Pr(>F)    
grupo          4   0.71    0.18    2.37  0.055 .  
origem         1   5.80    5.80   77.52  2e-15 ***
grupo:origem   4   0.79    0.20    2.63  0.037 *  
Residuals    160  11.98    0.07                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(aov(lm(value ~ grupo * origem, pos_gabarito$taxonomicos)))
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = lm(value ~ grupo * origem, pos_gabarito$taxonomicos))

$grupo
                           diff      lwr     upr  p adj
invertebrado-aves     -0.152016 -0.33512 0.03109 0.1533
mamifero-aves          0.002443 -0.18066 0.18554 1.0000
peixe-aves            -0.050865 -0.23397 0.13224 0.9398
reptil-aves           -0.130897 -0.31400 0.05221 0.2842
mamifero-invertebrado  0.154459 -0.02864 0.33756 0.1416
peixe-invertebrado     0.101150 -0.08195 0.28425 0.5483
reptil-invertebrado    0.021119 -0.16198 0.20422 0.9978
peixe-mamifero        -0.053308 -0.23641 0.12979 0.9293
reptil-mamifero       -0.133339 -0.31644 0.04976 0.2663
reptil-peixe          -0.080031 -0.26313 0.10307 0.7479

$origem
                  diff     lwr     upr p adj
nativa-exotica -0.3695 -0.4524 -0.2866     0

$`grupo:origem`
                                              diff     lwr       upr  p adj
invertebrado:exotica-aves:exotica        -0.033503 -0.3347  0.267652 1.0000
mamifero:exotica-aves:exotica             0.103885 -0.1973  0.405040 0.9834
peixe:exotica-aves:exotica                0.109394 -0.1918  0.410549 0.9764
reptil:exotica-aves:exotica              -0.143444 -0.4446  0.157711 0.8788
aves:nativa-aves:exotica                 -0.222463 -0.5236  0.078692 0.3507
invertebrado:nativa-aves:exotica         -0.492991 -0.7941 -0.191836 0.0000
mamifero:nativa-aves:exotica             -0.321463 -0.6226 -0.020307 0.0262
peixe:nativa-aves:exotica                -0.433588 -0.7347 -0.132433 0.0003
reptil:nativa-aves:exotica               -0.340812 -0.6420 -0.039657 0.0135
mamifero:exotica-invertebrado:exotica     0.137388 -0.1638  0.438544 0.9042
peixe:exotica-invertebrado:exotica        0.142898 -0.1583  0.444053 0.8812
reptil:exotica-invertebrado:exotica      -0.109941 -0.4111  0.191214 0.9756
aves:nativa-invertebrado:exotica         -0.188960 -0.4901  0.112195 0.5909
invertebrado:nativa-invertebrado:exotica -0.459488 -0.7606 -0.158333 0.0001
mamifero:nativa-invertebrado:exotica     -0.287959 -0.5891  0.013196 0.0739
peixe:nativa-invertebrado:exotica        -0.400085 -0.7012 -0.098930 0.0014
reptil:nativa-invertebrado:exotica       -0.307309 -0.6085 -0.006154 0.0414
peixe:exotica-mamifero:exotica            0.005509 -0.2956  0.306665 1.0000
reptil:exotica-mamifero:exotica          -0.247329 -0.5485  0.053826 0.2102
aves:nativa-mamifero:exotica             -0.326348 -0.6275 -0.025193 0.0223
invertebrado:nativa-mamifero:exotica     -0.596876 -0.8980 -0.295721 0.0000
mamifero:nativa-mamifero:exotica         -0.425347 -0.7265 -0.124192 0.0005
peixe:nativa-mamifero:exotica            -0.537473 -0.8386 -0.236318 0.0000
reptil:nativa-mamifero:exotica           -0.444697 -0.7459 -0.143542 0.0002
reptil:exotica-peixe:exotica             -0.252838 -0.5540  0.048317 0.1851
aves:nativa-peixe:exotica                -0.331858 -0.6330 -0.030703 0.0185
invertebrado:nativa-peixe:exotica        -0.602386 -0.9035 -0.301230 0.0000
mamifero:nativa-peixe:exotica            -0.430857 -0.7320 -0.129702 0.0004
peixe:nativa-peixe:exotica               -0.542982 -0.8441 -0.241827 0.0000
reptil:nativa-peixe:exotica              -0.450207 -0.7514 -0.149052 0.0002
aves:nativa-reptil:exotica               -0.079019 -0.3802  0.222136 0.9978
invertebrado:nativa-reptil:exotica       -0.349547 -0.6507 -0.048392 0.0099
mamifero:nativa-reptil:exotica           -0.178018 -0.4792  0.123137 0.6712
peixe:nativa-reptil:exotica              -0.290144 -0.5913  0.011011 0.0694
reptil:nativa-reptil:exotica             -0.197368 -0.4985  0.103787 0.5282
invertebrado:nativa-aves:nativa          -0.270528 -0.5717  0.030627 0.1192
mamifero:nativa-aves:nativa              -0.098999 -0.4002  0.202156 0.9881
peixe:nativa-aves:nativa                 -0.211125 -0.5123  0.090030 0.4278
reptil:nativa-aves:nativa                -0.118349 -0.4195  0.182806 0.9606
mamifero:nativa-invertebrado:nativa       0.171529 -0.1296  0.472684 0.7167
peixe:nativa-invertebrado:nativa          0.059403 -0.2418  0.360558 0.9998
reptil:nativa-invertebrado:nativa         0.152179 -0.1490  0.453334 0.8358
peixe:nativa-mamifero:nativa             -0.112126 -0.4133  0.189030 0.9722
reptil:nativa-mamifero:nativa            -0.019350 -0.3205  0.281805 1.0000
reptil:nativa-peixe:nativa                0.092776 -0.2084  0.393931 0.9926

5 - Estudantes que residem na Cidade 1 (com UC) identificam mais espécies nativas do que estudantes que residem na Cidade 2 (sem UC).

tmp <-
    merge(
        pos_gabarito$dados %>% 
            select(turmas, municipio) %>% 
            unique(),
        pos_gabarito$proporcoes$por_turma_area
    ) %>%
    select(municipio, area, value = p_nativas) %>%
    tbl_df()
# Realizando o teste T
t.test(value ~ municipio, tmp)

    Welch Two Sample t-test

data:  value by municipio
t = 0.83, df = 28, p-value = 0.4
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.06479  0.15254
sample estimates:
mean in group Bela Vista de Goiás            mean in group Silvânia 
                           0.3869                            0.3431 
tmp %>%
  ggplot() + 
  geom_boxplot(aes(x = area, y = value, fill = municipio), show.legend = T) + 
  scale_y_continuous(limits = c(0,1), labels = scales::percent) +
  facet_wrap(~municipio) +
  theme_bw() +
  labs(title = "Boxplot de identificação de espécies Nativas nos critérios estabelecidos",
       y = "Percentual de identificação", x = "") +
  my_theme

6 - Estudantes que residem em área rural tem maior conhecimento sobre as espécies nativas.

tmp <- 
    pos_gabarito$proporcoes$por_turma_area %>%
    select(municipio, area, p_nome_nativas = p_nativas, p_origem_nativas, p_indice_nativas) %>%
    arrange(area) %>%
    melt(id = c("municipio", "area"))
tmp <-
    cbind(tmp, colsplit(tmp$variable, "_", c("p", "indicador", "origem"))) %>%
    select(municipio, area, indicador, origem, value)
tmp %>%
  ggplot() + 
  geom_boxplot(aes(x = area, y = value, fill = municipio), show.legend = T) + 
  scale_y_continuous(limits = c(0,1), labels = scales::percent) +
  facet_wrap(~indicador) +
  theme_bw() +
  labs(title = "Boxplot de identificação de espécies Nativas nos critérios estabelecidos",
       y = "Percentual de identificação", x = "") +
  my_theme

#boxplot(value  ~ municipio + area, data = tmp)
# interaction.plot(tmp$area, tmp$municipio, tmp$value)
# interaction.plot(tmp$municipio, tmp$area, tmp$value)
# aggregate(value ~ area * municipio, data = tmp, FUN = function(x) shapiro.test(x)$p.value)
# tmp$bart = paste(tmp$municipio, "-", tmp$area)
# bartlett.test(value ~ bart, data = tmp)
t.anova <- anova(lm(value  ~ municipio * area, data = tmp %>% filter(indicador == "indice")))
t.anova %>%
    kable() %>%
    kable_styling(c("striped", "bordered"), full_width = TRUE) %>%
    column_spec(1, bold = TRUE)

Df Sum Sq Mean Sq F value Pr(>F)
municipio 1 0.0032 0.0032 0.1321 0.7189
area 1 0.0105 0.0105 0.4332 0.5156
municipio:area 1 0.0001 0.0001 0.0021 0.9633
Residuals 29 0.7057 0.0243 NA NA

tukey <- TukeyHSD(aov(lm(value  ~ municipio * area, data = tmp %>% filter(indicador == "indice"))))
tukey
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = lm(value ~ municipio * area, data = tmp %>% filter(indicador == "indice")))

$municipio
                                 diff     lwr     upr  p adj
Silvânia-Bela Vista de Goiás -0.01975 -0.1309 0.09138 0.7189

$area
                diff      lwr    upr  p adj
Urbana-Rural 0.03575 -0.07538 0.1469 0.5158

$`municipio:area`
                                                         diff     lwr    upr  p adj
Silvânia:Rural-Bela Vista de Goiás:Rural             -0.02339 -0.2359 0.1891 0.9904
Bela Vista de Goiás:Urbana-Bela Vista de Goiás:Rural  0.03318 -0.1793 0.2457 0.9737
Silvânia:Urbana-Bela Vista de Goiás:Rural             0.01483 -0.1917 0.2213 0.9973
Bela Vista de Goiás:Urbana-Silvânia:Rural             0.05658 -0.1559 0.2691 0.8861
Silvânia:Urbana-Silvânia:Rural                        0.03823 -0.1683 0.2447 0.9574
Silvânia:Urbana-Bela Vista de Goiás:Urbana           -0.01835 -0.2249 0.1882 0.9949
#plot(tukey)
tk <- as.data.frame(tukey$`municipio:area`)
tk$comparacao = rownames(tk)
rownames(tk) = NULL
tk %>%
    select(comparacao, diff:`p adj`) %>%
    mutate(significancia = `p adj` <= 0.05) %>%
    kable() %>%
    kable_styling(c("striped", "bordered"), full_width = TRUE) %>%
    column_spec(1, bold = TRUE)
comparacao diff lwr upr p adj significancia
Silvânia:Rural-Bela Vista de Goiás:Rural -0.0234 -0.2359 0.1891 0.9904 FALSE
Bela Vista de Goiás:Urbana-Bela Vista de Goiás:Rural 0.0332 -0.1793 0.2457 0.9737 FALSE
Silvânia:Urbana-Bela Vista de Goiás:Rural 0.0148 -0.1917 0.2213 0.9973 FALSE
Bela Vista de Goiás:Urbana-Silvânia:Rural 0.0566 -0.1559 0.2691 0.8861 FALSE
Silvânia:Urbana-Silvânia:Rural 0.0382 -0.1683 0.2447 0.9574 FALSE
Silvânia:Urbana-Bela Vista de Goiás:Urbana -0.0184 -0.2249 0.1882 0.9949 FALSE

7 - Frequencia de contato natureza

tmp <- 
    pos_gabarito$proporcoes$por_turma_freq_contato %>%
    select(frequencia, p_nome_nativas = p_nativas, p_origem_nativas, p_indice_nativas) %>%
    arrange(frequencia) %>%
    melt(id = "frequencia")
tmp <-
    cbind(tmp, colsplit(tmp$variable, "_", c("p", "indicador", "origem"))) %>%
    select(frequencia, indicador, origem, value)
tmp %>%
  ggplot() + 
  geom_boxplot(aes(x = frequencia, y = value, fill = frequencia), show.legend = T) + 
  scale_y_continuous(limits = c(0,1), labels = scales::percent) +
  facet_wrap(~indicador) +
  theme_bw() +
  labs(title = "Boxplot de identificação de espécies Nativas nos critérios estabelecidos",
       y = "Percentual de identificação", x = "") +
  my_theme

# aggregate(value ~ frequencia, 
#           data = tmp %>% filter(indicador == "indice"), 
#           FUN = function(x) shapiro.test(x)$p.value)
t.anova <- anova(lm(value  ~ frequencia, data = tmp %>% filter(indicador == "indice")))
t.anova %>%
    kable() %>%
    kable_styling(c("striped", "bordered"), full_width = TRUE) %>%
    column_spec(1, bold = TRUE)

Df Sum Sq Mean Sq F value Pr(>F)
frequencia 4 0.1316 0.0329 1.279 0.2883
Residuals 61 1.5693 0.0257 NA NA

tukey <- TukeyHSD(aov(lm(value  ~ frequencia, data = tmp %>% filter(indicador == "indice"))))
tukey
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = lm(value ~ frequencia, data = tmp %>% filter(indicador == "indice")))

$frequencia
                              diff      lwr    upr  p adj
Raramente-Nunca           0.370714 -0.09599 0.8374 0.1816
Ás vezes-Nunca            0.325893 -0.13806 0.7898 0.2906
Frequentemente-Nunca      0.332468 -0.13148 0.7964 0.2716
Sempre-Nunca              0.334260 -0.12969 0.7982 0.2665
Ás vezes-Raramente       -0.044821 -0.20755 0.1179 0.9371
Frequentemente-Raramente -0.038247 -0.20097 0.1245 0.9639
Sempre-Raramente         -0.036454 -0.19918 0.1263 0.9697
Frequentemente-Ás vezes   0.006574 -0.14808 0.1612 1.0000
Sempre-Ás vezes           0.008367 -0.14628 0.1630 0.9999
Sempre-Frequentemente     0.001793 -0.15286 0.1564 1.0000
#plot(tukey)
tk <- as.data.frame(tukey$frequencia)
tk$comparacao = rownames(tk)
rownames(tk) = NULL
tk %>%
    select(comparacao, diff:`p adj`) %>%
    mutate(significancia = `p adj` <= 0.05) %>%
    kable() %>%
    kable_styling(c("striped", "bordered"), full_width = TRUE) %>%
    column_spec(1, bold = TRUE)
comparacao diff lwr upr p adj significancia
Raramente-Nunca 0.3707 -0.0960 0.8374 0.1816 FALSE
Ás vezes-Nunca 0.3259 -0.1381 0.7898 0.2906 FALSE
Frequentemente-Nunca 0.3325 -0.1315 0.7964 0.2716 FALSE
Sempre-Nunca 0.3343 -0.1297 0.7982 0.2665 FALSE
Ás vezes-Raramente -0.0448 -0.2075 0.1179 0.9371 FALSE
Frequentemente-Raramente -0.0382 -0.2010 0.1245 0.9639 FALSE
Sempre-Raramente -0.0365 -0.1992 0.1263 0.9697 FALSE
Frequentemente-Ás vezes 0.0066 -0.1481 0.1612 1.0000 FALSE
Sempre-Ás vezes 0.0084 -0.1463 0.1630 0.9999 FALSE
Sempre-Frequentemente 0.0018 -0.1529 0.1564 1.0000 FALSE

8 - Fez aulas praticas

tmp <- 
    pos_gabarito$proporcoes$por_turma_fez_aula %>%
    select(fez.aula, p_nome_nativas = p_nativas, p_origem_nativas, p_indice_nativas) %>%
    arrange(fez.aula) %>%
    melt(id = "fez.aula")
tmp <- cbind(tmp, colsplit(tmp$variable, "_", c("p", "indicador", "origem"))) %>%
  select(fez.aula, indicador, origem, value) 
tmp %>%
  ggplot() + 
  geom_boxplot(aes(x = fez.aula, y = value, fill = fez.aula), show.legend = T) + 
  scale_y_continuous(limits = c(0,1), labels = scales::percent) +
  facet_wrap(~indicador) +
  theme_bw() +
  labs(title = "Boxplot de identificação de espécies Nativas nos critérios estabelecidos - Alunos que fizeram aula",
       y = "Percentual de identificação", x = "") +
  my_theme

anova_fez.aula <- teste.anova(formula = value ~ fez.aula, 
            data = tmp %>% filter(indicador == "indice"))
anova_fez.aula$teste.normalidade

fez.aula value H0 normalidade
Não fez 0.4445 FALSE FALSE
Sim, fazenda 0.6779 FALSE FALSE
Sim, FLONA 0.2359 FALSE FALSE
Sim, memorial do cerrado 0.8784 FALSE FALSE
Sim, outro 0.2117 FALSE FALSE
Sim, parque ou trilha 0.0414 TRUE TRUE
Sim, zoologico 0.4950 FALSE FALSE

anova_fez.aula$teste.anova
Analysis of Variance Table

Response: value
          Df Sum Sq Mean Sq F value Pr(>F)
fez.aula   6  0.127  0.0212    0.62   0.71
Residuals 61  2.085  0.0342               
anova_fez.aula$tabela.tukey
comparacao diff lwr upr p adj significancia
Sim, fazenda-Não fez -0.1000 -0.3867 0.1868 0.9364 FALSE
Sim, FLONA-Não fez 0.0446 -0.1971 0.2863 0.9976 FALSE
Sim, memorial do cerrado-Não fez 0.0481 -0.2050 0.3012 0.9972 FALSE
Sim, outro-Não fez 0.0467 -0.2210 0.3143 0.9983 FALSE
Sim, parque ou trilha-Não fez -0.0155 -0.2088 0.1779 1.0000 FALSE
Sim, zoologico-Não fez 0.0675 -0.1742 0.3092 0.9781 FALSE
Sim, FLONA-Sim, fazenda 0.1446 -0.1768 0.4659 0.8144 FALSE
Sim, memorial do cerrado-Sim, fazenda 0.1481 -0.1820 0.4781 0.8164 FALSE
Sim, outro-Sim, fazenda 0.1467 -0.1946 0.4880 0.8446 FALSE
Sim, parque ou trilha-Sim, fazenda 0.0845 -0.2023 0.3713 0.9715 FALSE
Sim, zoologico-Sim, fazenda 0.1675 -0.1538 0.4888 0.6895 FALSE
Sim, memorial do cerrado-Sim, FLONA 0.0035 -0.2882 0.2952 1.0000 FALSE
Sim, outro-Sim, FLONA 0.0021 -0.3023 0.3065 1.0000 FALSE
Sim, parque ou trilha-Sim, FLONA -0.0601 -0.3017 0.1816 0.9880 FALSE
Sim, zoologico-Sim, FLONA 0.0229 -0.2589 0.3047 1.0000 FALSE
Sim, outro-Sim, memorial do cerrado -0.0014 -0.3150 0.3122 1.0000 FALSE
Sim, parque ou trilha-Sim, memorial do cerrado -0.0636 -0.3167 0.1896 0.9874 FALSE
Sim, zoologico-Sim, memorial do cerrado 0.0194 -0.2723 0.3112 1.0000 FALSE
Sim, parque ou trilha-Sim, outro -0.0622 -0.3298 0.2055 0.9916 FALSE
Sim, zoologico-Sim, outro 0.0208 -0.2836 0.3252 1.0000 FALSE
Sim, zoologico-Sim, parque ou trilha 0.0830 -0.1587 0.3247 0.9406 FALSE

9 - Estudantes da Cidade 1 (com UC) tem maior número de acertos de espécies nativas.

tmp <- 
    pos_gabarito$proporcoes$por_turma_flona %>%
    select(flona, p_nome_nativas = p_nativas, p_origem_nativas, p_indice_nativas) %>%
    arrange(flona) %>%
    melt(id = "flona")
tmp <- cbind(tmp, colsplit(tmp$variable, "_", c("p", "indicador", "origem"))) %>%
  select(flona, indicador, origem, value) 
tmp %>%
  ggplot() + 
  geom_boxplot(aes(x = flona, y = value, fill = flona), show.legend = T) + 
  scale_y_continuous(limits = c(0,1), labels = scales::percent) +
  facet_wrap(~indicador) +
  theme_bw() +
  labs(title = "Boxplot de identificação de espécies Nativas nos critérios estabelecidos - Alunos que visitaram a Flona",
       y = "Percentual de identificação", x = "") +
  my_theme

anova_flona <- teste.anova(formula = value ~ flona, 
            data = tmp %>% filter(indicador == "indice"))
anova_flona$teste.normalidade

flona value H0 normalidade
Não 0.2036 FALSE FALSE
Sim 0.0249 TRUE TRUE

anova_flona$teste.anova
Analysis of Variance Table

Response: value
          Df Sum Sq Mean Sq F value Pr(>F)
flona      1  0.015  0.0147    0.48    0.5
Residuals 16  0.485  0.0303               
anova_flona$tabela.tukey
comparacao diff lwr upr p adj significancia
Sim-Não 0.0571 -0.1168 0.2311 0.4962 FALSE

10 - Ranking dos animais

a1 <- 
    pos_gabarito$raking_animais$nativos %>%
    head(20) %>%
    ggplot(aes(x = animais, y = freq, fill = freq)) +
    geom_bar(stat="identity", show.legend = F) +
    geom_text(aes(label = freq), position = position_dodge(0.9), vjust = -1, hjust = 0.5) +
    scale_y_continuous(limits = c(0,90)) +
    scale_fill_gradient(low = "orange", high = "red") +
    theme_bw() +
    labs(title = "Espécies citadas como nativas",
       y = "Frequencia", x = "") +
    my_theme
a2 <- 
    pos_gabarito$raking_animais$exoticos %>%
    head(20) %>%
    ggplot(aes(x = animais, y = freq, fill = freq)) +
    geom_bar(stat="identity", show.legend = F) +
    geom_text(aes(label = freq), position = position_dodge(0.9), vjust = -1, hjust = 0.5) +
    scale_y_continuous(limits = c(0,90)) +
    scale_fill_gradient(low = "lightblue", high = "darkblue") +
    theme_bw() +
    labs(title = "Espécies citadas como exóticas",
       y = "Frequencia", x = "") +
    my_theme
grid.arrange(a1, a2,
             nrow = 2,
             top = textGrob("TOP 20 - Ranking das espécies citadas como exemplo\n", 
                            gp = gpar(fontsize = 20, font = 2))
)

11 - Ranking dos animais citados para proteção

a3 <- 
    pos_gabarito$raking_animais$protegidos %>%
    head(20) %>%
    ggplot(aes(x = animais, y = freq, fill = freq)) +
    geom_bar(stat="identity", show.legend = F) +
    geom_text(aes(label = freq), position = position_dodge(0.9), vjust = -1, hjust = 0.5) +
    scale_y_continuous(limits = c(0,190)) +
    scale_fill_gradient(low = "green", high = "darkgreen") +
    theme_bw() +
    labs(title = "Espécies citadas como nativas",
       y = "Frequencia", x = "") +
    my_theme
grid.arrange(a3,
             top = textGrob("TOP 20 - Ranking das espécies citadas como exemplo para proteção\n", 
                            gp = gpar(fontsize = 20, font = 2))
)

LS0tCnRpdGxlOiAiTWVzdHJhZG8gQmlvbG9naWEiCmF1dGhvcjogIkhlcnNvbiBNZWxvIgpkYXRlOiAiMjgvMDYvMjAxOCIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IAogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNQotLS0KCmBgYHtyLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRSwgaW5jbHVkZSA9IEZBTFNFfQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KHJlc2hhcGUyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KGdyaWQpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkobm9ydGVzdCkKbGlicmFyeShzdGF0cykKbGlicmFyeShtdWx0Y29tcFZpZXcpCgpzdXBwcmVzc1dhcm5pbmdzKFN5cy5zZXRsb2NhbGUoIkxDX0FMTCIsICdlbl9VUy5VVEYtOCcpKQojb3B0aW9ucyhzY2lwZW4gPSA5OTksIGRpZ2l0cyA9IDQpCm9wdGlvbnMoc2NpcGVuID0gMCwgZGlnaXRzID0gNCkKIyBvcHRpb25zKCJzY2lwZW4iPS0xMDAsICJkaWdpdHMiPTYpCiMgZ2V0d2QoKQpsb2FkKCJkYWRvcy5SRGF0YSIpCgoKbXlfdGhlbWUgPC0gCiAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDI1LCBoanVzdCA9IDEsIHNpemUgPSAxMiksIAogICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2LCBmYWNlID0gImJvbGQiKSwKICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKQoKbm9ybWFsaWRhZGUgPC0gZnVuY3Rpb24oeCkgewogICAgdDEgPC0gc2hhcGlyby50ZXN0KHgpCiAgICB0MiA8LSBzZi50ZXN0KHgpCiAgICB0MyA8LSBsaWxsaWUudGVzdCh4KQogICAgdDQgPC0gYWQudGVzdCh4KQogICAgdDUgPC0gY3ZtLnRlc3QoeCkKICAgIHJldHVybiggZGF0YS5mcmFtZSgKICAgICAgICBBbGdvcml0bW8gPSBjKHQxJG1ldGhvZCwgdDIkbWV0aG9kLCAKICAgICAgICAgICAgICAgICAgIHQzJG1ldGhvZCwgdDQkbWV0aG9kLCAKICAgICAgICAgICAgICAgICAgIHQ1JG1ldGhvZCksCiAgICAgICAgcC52YWxvciA9IGModDEkcC52YWx1ZSwgdDIkcC52YWx1ZSwgCiAgICAgICAgICAgICAgICAgICAgdDMkcC52YWx1ZSwgdDQkcC52YWx1ZSwgCiAgICAgICAgICAgICAgICAgICAgdDUkcC52YWx1ZSksCiAgICAgICAgTm9ybWFsaWRhZGUgPSBjKHQxJHAudmFsdWUgPiAuMDUsIHQyJHAudmFsdWUgPiAuMDUsIAogICAgICAgICAgICAgICAgICAgICAgdDMkcC52YWx1ZSA+IC4wNSwgdDQkcC52YWx1ZSA+IC4wNSwgCiAgICAgICAgICAgICAgICAgICAgICB0NSRwLnZhbHVlID4gLjA1KQogICAgKSkKfQojIEltcGxlbWVudGFuZG8gZm9ybXVsYSBwYXJhIHRlc3RlcyBlc3RhdMOtc3RpY29zIHBhZHJvbml6YWRhCnRlc3RlLmFub3ZhIDwtIGZ1bmN0aW9uKGZvcm11bGEsIGRhdGEpIHsKICAgIHQubm9ybWFsaWRhZGUgPC0gCiAgICAgICAgYWdncmVnYXRlKGZvcm11bGEsIGRhdGEsIAogICAgICAgICAgICAgICAgICBGVU4gPSBmdW5jdGlvbih4KSBzaGFwaXJvLnRlc3QoeCkkcC52YWx1ZSkgJT4lCiAgICAgICAgbXV0YXRlKEgwID0gKHZhbHVlIDw9IDAuMDUpLAogICAgICAgICAgICAgICBub3JtYWxpZGFkZSA9IGNlbGxfc3BlYyhIMCwgYm9sZCA9IEgwLAogICAgICAgICAgICAgICAgICAgY29sb3I9IGlmZWxzZShIMCwgIndoaXRlIiwgImJsYWNrIiksIAogICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZCA9IGlmZWxzZShIMCwgImdyZWVuIiwgIiNDQ0NDQ0MiKSkKICAgICAgICAgICAgICAgKSAlPiUKICAgICAgICBrYWJsZShlc2NhcGUgPSBGKSAlPiUKICAgICAgICBrYWJsZV9zdHlsaW5nKGMoInN0cmlwZWQiLCAiYm9yZGVyZWQiKSwgZnVsbF93aWR0aCA9IFRSVUUpICU+JQogICAgICAgIGNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUUlVFKQoKICAgIHQuYW5vdmEgPC0gYW5vdmEobG0oZm9ybXVsYSwgZGF0YSkpCiAgICB0LnR1a2V5IDwtIFR1a2V5SFNEKGFvdihsbShmb3JtdWxhLCBkYXRhKSkpCgogICAgaWYobGVuZ3RoKHQudHVrZXkpID4gMSkgewogICAgICAgIGVycm9yKCJBTk9WQSBmYXRvcmlhbCAoZmFsdGEgdHJhdGFyIGlzc28pISIpCiAgICB9CiAgICB0dWtleS50YmwgPC0gYXMuZGF0YS5mcmFtZSh0LnR1a2V5W1sxXV0sIGN1dC5uYW1lcyA9IEYpCiAgICB0dWtleS50YmwkY29tcGFyYWNhbyA9IHJvd25hbWVzKHR1a2V5LnRibCkKICAgIHJvd25hbWVzKHR1a2V5LnRibCkgPSBOVUxMCiAgICB0YWJlbGEudHVrZXkgPC0gdHVrZXkudGJsICU+JQogICAgICAgIG11dGF0ZShIMCA9IChgcCBhZGpgIDw9IDAuMDUpLAogICAgICAgICAgICAgICBzaWduaWZpY2FuY2lhID0gY2VsbF9zcGVjKEgwLCBib2xkID0gSDAsCiAgICAgICAgICAgICAgICAgICBjb2xvcj0gaWZlbHNlKEgwLCAid2hpdGUiLCAiYmxhY2siKSwgCiAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kID0gaWZlbHNlKEgwLCAiZ3JlZW4iLCAiI0NDQ0NDQyIpKQogICAgICAgICAgICAgICApICU+JQogICAgICAgIHNlbGVjdChjb21wYXJhY2FvLCBkaWZmOmBwIGFkamAsIHNpZ25pZmljYW5jaWEpICU+JQogICAgICAgIGthYmxlKGVzY2FwZSA9IEYpICU+JQogICAgICAgIGthYmxlX3N0eWxpbmcoYygic3RyaXBlZCIsICJib3JkZXJlZCIpLCBmdWxsX3dpZHRoID0gVFJVRSkgJT4lCiAgICAgICAgY29sdW1uX3NwZWMoMSwgYm9sZCA9IFRSVUUpCiAgICAKICAgICAgICAKICAgIHJlc3VsdGFkbyA8LSAKICAgICAgICBsaXN0KAogICAgICAgICAgICB0ZXN0ZS5ub3JtYWxpZGFkZSA9IHQubm9ybWFsaWRhZGUsCiAgICAgICAgICAgIHRlc3RlLmFub3ZhID0gdC5hbm92YSwKICAgICAgICAgICAgdHVrZXkgPSB0LnR1a2V5LAogICAgICAgICAgICB0YWJlbGEudHVrZXkgPSB0YWJlbGEudHVrZXkKICAgICAgICApCiAgICByZXR1cm4ocmVzdWx0YWRvKQp9CgppYy5tZWRpYSA8LSBmdW5jdGlvbih2ZXRvckRhZG9zKXsKICAgICMjIwogICAgIyMgQ2FsY3VsYW5kbyBvIGludGVydmFsbyBkZSBjb25maWFuw6dhCiAgICAjIyMKICAgIG1lZGlhIDwtIG1lYW4odmV0b3JEYWRvcykgI23DqWRpYSBkYSBhbW9zdHJhCiAgICBzIDwtIHNkKHZldG9yRGFkb3MpICNkZXN2aW8gcGFkcsOjbwogICAgbiA8LSBsZW5ndGgodmV0b3JEYWRvcykgI3RhbWFuaG8gZGEgYW1vc3RyYQogICAgZXJyb1BhZHJhbyA8LSBxbm9ybSgwLjk3NSkqcy9zcXJ0KG4pCiAgICBsaW1pdGUgPC0gMS45NiAqIGVycm9QYWRyYW8KICAgIGVycm9yLmluZmVyaW9yIDwtIG1lZGlhIC0gZXJyb1BhZHJhbwogICAgZXJyb3Iuc3VwZXJpb3IgPC0gbWVkaWEgKyBlcnJvUGFkcmFvCiAgICBsaW1pdGUuaW5mZXJpb3IgPC0gbWVkaWEgLSBsaW1pdGUKICAgIGxpbWl0ZS5zdXBlcmlvciA8LSBtZWRpYSArIGxpbWl0ZQogICAgcmV0dXJuKGRhdGEuZnJhbWUoCiAgICAgICAgbWVkaWEsIAogICAgICAgIGRlc3ZpbyA9IHMsIAogICAgICAgIGVycm9QYWRyYW8sIAogICAgICAgIGVycm9yLmluZmVyaW9yLCBlcnJvci5zdXBlcmlvciwgCiAgICAgICAgbGltaXRlLmluZmVyaW9yLCBsaW1pdGUuc3VwZXJpb3IpKQp9CgpwbG90QW5hbGlzZU1lZGlhcyA8LSBmdW5jdGlvbih2ZXRvckV4b3RpY2FzLCB2ZXRvck5hdGl2YXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXR1bG8gPSAiIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHl0ZXh0ID0gIk3DqWRpYSBwZXJjZW50dWFsIGRlIGFjZXJ0b3NcbiIpIHsKICAgIHRtcCA8LSByYmluZCgKICAgICAgICBjYmluZChvcmlnZW0gPSAiRXhvdGljYXMiLCBpYy5tZWRpYSh2ZXRvckV4b3RpY2FzKSksCiAgICAgICAgY2JpbmQob3JpZ2VtID0gIk5hdGl2YXMiLCBpYy5tZWRpYSh2ZXRvck5hdGl2YXMpKQogICAgKQogICAgIyBsaW1pdGVzRXNjYWxhID0gYyhtaW4odG1wJGxpbWl0ZS5pbmZlcmlvcikqMC44LCAjIDIwJSBhIG1lbm9zIGRvIG1lbm9yIGxpbWl0ZSBpbmZlcmlvciAKICAgICMgICAgICAgICAgICAgICAgICAgbWF4KHRtcCRsaW1pdGUuc3VwZXJpb3IpKjEuMikgIyAyMCUgYSBtYWlzIGRvIG1lbm9yIGxpbWl0ZSBzdXBlcmlvciAKICAgIGxpbWl0ZXNFc2NhbGEgPC0gYygwLDEpCiAgICAKICAgIHAgPC0gZ2dwbG90KHRtcCwgYWVzKG9yaWdlbSwgbWVkaWEpKSArCiAgICAgICAgI2dlb21fcmVjdCgpCiAgICAgICAgZ2VvbV9jcm9zc2JhcihhZXMoeW1pbiA9IGVycm9yLmluZmVyaW9yLCB5bWF4ID0gZXJyb3Iuc3VwZXJpb3IpLCB3aWR0aCA9IDAuMSkgKwogICAgICAgIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBsaW1pdGUuaW5mZXJpb3IsIHltYXggPSBsaW1pdGUuc3VwZXJpb3IpLCB3aWR0aCA9IDAuMSkgKwogICAgICAgIGdlb21fcG9pbnQoYWVzKG9yaWdlbSwgbWVkaWEpKSArCiAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGxpbWl0ZXNFc2NhbGEsIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkgKwogICAgICAgIGxhYnModGl0bGUgPSB0aXR1bG8sCiAgICAgICAgICAgICB4ID0gIiIsCiAgICAgICAgICAgICB5ID0geXRleHQpICsgCiAgICAgICAgbXlfdGhlbWUgKyAKICAgICAgICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQogICAgcmV0dXJuKHApCn0KYGBgCgojIyBBbsOhbGlzZSBkbyBKb2dvIGRlIEltYWdlbnMgYXBsaWNhZGFzIG5vIEVuc2lubyBtw6lkaW8KCgojIyMgQW1vc3RyYSBkb3MgZGFkb3MgZGEgcGVzcXVpc2EgcmVhbGl6YWRhCgpUYWJ1bGHDp8OjbyBkbyBuw7ptZXJvIGRlIGFjZXJ0b3MgZG9zIGl0ZW5zIGRvIGpvZ28gZGUgaW1hZ2Vucy4KCmBgYHtyLCBlY2hvPUZBTFNFfQpkZXNjX2NvbHVuYXMgPC0gZGF0YS5mcmFtZSgKICAgICJDb2x1bmEiID0gYygiRXhvdGljYXMiLCAiTmF0aXZhcyIpLAogICAgIkRlc2NyacOnw6NvIiA9IGMoIk7Dum1lcm8gZGUgYWNlcnRvcyBkZW50cmUgdG9kYXMgYXMgaW1hZ2VucyBleGliaWRhcyBkbyB0aXBvIGV4w7N0aWNhLCB2YWxvciBleHBlcmFkbyDDqSA1LiIsCiAgICAgICAgICAgICAgICAgICAgIk7Dum1lcm8gZGUgYWNlcnRvcyBkZW50cmUgdG9kYXMgYXMgaW1hZ2VucyBleGliaWRhcyBkbyB0aXBvIG5hdGl2YSwgdmFsb3IgZXhwZXJhZG8gw6kgNS4iKQogICAgKQpkZXNjX2NvbHVuYXMgJT4lCiAga2FibGUoKSAlPiUKICBrYWJsZV9zdHlsaW5nKGMoInN0cmlwZWQiLCAiYm9yZGVyZWQiKSwgZnVsbF93aWR0aCA9IFRSVUUpICU+JQogIGNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUUlVFKQoKYGBgCgoKYGBge3J9CmhlYWQocG9zX2dhYmFyaXRvJGRhZG9zLCAxMCkKYGBgCgojIyMjIERldGVybWluYWRvIGEgdGF4YSBkZSBwZXJjZXDDp8OjbwoKRW50ZW5kZS1zZSBwb3IgdGF4YSBkZSBwZXJjZXDDp8OjbyBvIGZhdG9yIGRldGVybWluYWRvIHBlbGEgcXVhbnRpZGFkZSBtw6lkaWEgZGUgYWNlcnRvcyBkZW50cmUgYXMgcXVlc3TDtWVzIGFwcmVzZW50YWRhcyBhb3MgYWx1bm9zLCBlbSByZWxhw6fDo28gYSB0dXJtYSBlbSBxdWUgbyBxdWVzdGlvbmFyaW8gZm9pIGFwbGljYWRvLgoKUGVyY2Vww6fDo28gZG9zIGFsdW5vcwoKYGBge3J9CnByaW50KHBvc19nYWJhcml0byRwZXJjZW50dWFsX2FjZXJ0bykKYGBgCgojIyMjIEVudGVuZGVuZG8gYSBkaXN0cmlidWnDp8OjbyBkYXMgbcOpZGlhcwoKTsOtdmVpcyBkZSByZWNvbmhlY2ltZW50byAoYWNlcnRvcykgcG9yIHRpcG8gZGUgb3JpZ2VtIGRvcyBhbmltYWlzCgpgYGB7ciwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NH0KZ3JpZC5hcnJhbmdlKAogICAgcGxvdEFuYWxpc2VNZWRpYXMocG9zX2dhYmFyaXRvJHBlcmNlbnR1YWxfYWNlcnRvJHBfbm9tZV9leG90aWNhcywKICAgICAgICAgICAgICAgICAgcG9zX2dhYmFyaXRvJHBlcmNlbnR1YWxfYWNlcnRvJHBfbm9tZV9uYXRpdmFzLAogICAgICAgICAgICAgICAgICAiSWRlbnRpZmljYcOnw6NvIGRvcyBub21lcyIpLAogICAgcGxvdEFuYWxpc2VNZWRpYXMocG9zX2dhYmFyaXRvJHBlcmNlbnR1YWxfYWNlcnRvJHBfb3JpZ2VtX2V4b3RpY2FzLAogICAgICAgICAgICAgICAgICBwb3NfZ2FiYXJpdG8kcGVyY2VudHVhbF9hY2VydG8kcF9vcmlnZW1fbmF0aXZhcywKICAgICAgICAgICAgICAgICAgIklkZW50aWZpY2HDp8OjbyBkYXMgb3JpZ2VucyIsIHkgPSAiIiksCiAgICBwbG90QW5hbGlzZU1lZGlhcyhwb3NfZ2FiYXJpdG8kcGVyY2VudHVhbF9hY2VydG8kcF9pbmRpY2VfZXhvdGljYXMsCiAgICAgICAgICAgICAgICAgIHBvc19nYWJhcml0byRwZXJjZW50dWFsX2FjZXJ0byRwX2luZGljZV9uYXRpdmFzLAogICAgICAgICAgICAgICAgICAiVGF4YSBkZSByZWNvbmhlY2ltZW50byIsIHkgPSAiIiksIAogICAgbmNvbCA9IDMsCiAgICB0b3AgPSB0ZXh0R3JvYigiTml2ZWlzIGRlIHJlY29uaGVjaW1lbnRvIHBvciBvcmlnZW1cbiIsIAogICAgICAgICAgICAgICAgICAgZ3AgPSBncGFyKGZvbnRzaXplID0gMjAsIGZvbnQgPSAyKSksCiAgICByaWdodCA9ICJcbiIKKQpgYGAKCkRpZmVyZW7Dp2EgZGUgYWNlcnRvcwoKYGBge3IsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTR9CmdyaWQuYXJyYW5nZSgKICAgIGdncGxvdChwb3NfZ2FiYXJpdG8kZGFkb3MsIGFlcyhleG90aWNhcyAtIG5hdGl2YXMpKSArCiAgICAgICAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDkpICsKICAgICAgICBsYWJzKHRpdGxlID0gIklkZW50aWZpY2HDp8OjbyBkb3Mgbm9tZXMiLCB5ID0gIlRvdGFsIGRlIGFjZXJ0b3MiKSArCiAgICAgICAgbXlfdGhlbWUsCiAgICBnZ3Bsb3QocG9zX2dhYmFyaXRvJGRhZG9zLCBhZXMob3JpZ2VtX2V4b3RpY2FzIC0gb3JpZ2VtX25hdGl2YXMpKSArCiAgICAgICAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDkpICsKICAgICAgICBsYWJzKHRpdGxlID0gIklkZW50aWZpY2HDp8OjbyBkYXMgb3JpZ2VucyIsIHkgPSAiIikgKwogICAgICAgIG15X3RoZW1lLAogICAgZ2dwbG90KHBvc19nYWJhcml0byRkYWRvcywgYWVzKGluZGljZV9leG90aWNhcyAtIGluZGljZV9uYXRpdmFzKSkgKwogICAgICAgIGdlb21faGlzdG9ncmFtKGJpbnMgPSA5KSArCiAgICAgICAgbGFicyh0aXRsZSA9ICJUYXhhIGRlIHJlY29uaGVjaW1lbnRvIiwgeSA9ICIiKSArCiAgICAgICAgbXlfdGhlbWUsIAogICAgZ2d0ZXh0dGFibGUobm9ybWFsaWRhZGUocG9zX2dhYmFyaXRvJGRhZG9zJGV4b3RpY2FzIC0gcG9zX2dhYmFyaXRvJGRhZG9zJG5hdGl2YXMpLAogICAgICAgICAgICAgICAgcm93cyA9IE5VTEwsIHRoZW1lID0gdHRoZW1lKGJhc2Vfc3R5bGUgPSAibU9yYW5nZSIsIGJhc2Vfc2l6ZSA9IDkpKSwKICAgIGdndGV4dHRhYmxlKG5vcm1hbGlkYWRlKHBvc19nYWJhcml0byRkYWRvcyRvcmlnZW1fZXhvdGljYXMgLSBwb3NfZ2FiYXJpdG8kZGFkb3Mkb3JpZ2VtX25hdGl2YXMpLAogICAgICAgICAgICAgICAgcm93cyA9IE5VTEwsIHRoZW1lID0gdHRoZW1lKGJhc2Vfc3R5bGUgPSAibU9yYW5nZSIsIGJhc2Vfc2l6ZSA9IDkpKSwKICAgIGdndGV4dHRhYmxlKG5vcm1hbGlkYWRlKHBvc19nYWJhcml0byRkYWRvcyRpbmRpY2VfZXhvdGljYXMgLSBwb3NfZ2FiYXJpdG8kZGFkb3MkaW5kaWNlX25hdGl2YXMpLAogICAgICAgICAgICAgICAgcm93cyA9IE5VTEwsIHRoZW1lID0gdHRoZW1lKGJhc2Vfc3R5bGUgPSAibU9yYW5nZSIsIGJhc2Vfc2l6ZSA9IDkpKSwKICAgIG5jb2wgPSAzLAogICAgdG9wID0gdGV4dEdyb2IoIkhpc3RvZ3JhbWEgZGFzIGRpZmVyZW7Dp2FzIEV4b3RpY2FzIHggTmF0aXZhc1xuIiwgCiAgICAgICAgICAgICAgICAgICBncCA9IGdwYXIoZm9udHNpemUgPSAyMCwgZm9udCA9IDIpKSwKICAgIGhlaWdodHM9YygzLzQsIDEvNCksCiAgICByaWdodCA9ICJcbiIsCiAgICBib3R0b20gPSAiXG4iCikKYGBgCgpHcnVwb3MgdGF4b27Ds21pY29zCgpgYGB7ciwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NH0KZ3JpZC5hcnJhbmdlKAogICAgcGxvdEFuYWxpc2VNZWRpYXMocG9zX2dhYmFyaXRvJHBlcmNlbnR1YWxfYWNlcnRvJHBfZXhvdGljYV9hdmVzLAogICAgICAgICAgICAgICAgICBwb3NfZ2FiYXJpdG8kcGVyY2VudHVhbF9hY2VydG8kcF9uYXRpdmFfYXZlcywKICAgICAgICAgICAgICAgICAgIkF2ZXMiKSwKICAgIHBsb3RBbmFsaXNlTWVkaWFzKHBvc19nYWJhcml0byRwZXJjZW50dWFsX2FjZXJ0byRwX2V4b3RpY2FfaW52ZXJ0ZWJyYWRvLAogICAgICAgICAgICAgICAgICBwb3NfZ2FiYXJpdG8kcGVyY2VudHVhbF9hY2VydG8kcF9uYXRpdmFfaW52ZXJ0ZWJyYWRvLAogICAgICAgICAgICAgICAgICAiSW52ZXJ0ZWJyYWRvcyIsIHkgPSAiIiksCiAgICBwbG90QW5hbGlzZU1lZGlhcyhwb3NfZ2FiYXJpdG8kcGVyY2VudHVhbF9hY2VydG8kcF9leG90aWNhX21hbWlmZXJvLAogICAgICAgICAgICAgICAgICBwb3NfZ2FiYXJpdG8kcGVyY2VudHVhbF9hY2VydG8kcF9uYXRpdmFfbWFtaWZlcm8sCiAgICAgICAgICAgICAgICAgICJNYW1pZmVyb3MiLCB5ID0gIiIpLCAKICAgIHBsb3RBbmFsaXNlTWVkaWFzKHBvc19nYWJhcml0byRwZXJjZW50dWFsX2FjZXJ0byRwX2V4b3RpY2FfcGVpeGUsCiAgICAgICAgICAgICAgICAgIHBvc19nYWJhcml0byRwZXJjZW50dWFsX2FjZXJ0byRwX25hdGl2YV9wZWl4ZSwKICAgICAgICAgICAgICAgICAgIk1hbWlmZXJvcyIsIHkgPSAiIiksIAogICAgcGxvdEFuYWxpc2VNZWRpYXMocG9zX2dhYmFyaXRvJHBlcmNlbnR1YWxfYWNlcnRvJHBfZXhvdGljYV9yZXB0aWwsCiAgICAgICAgICAgICAgICAgIHBvc19nYWJhcml0byRwZXJjZW50dWFsX2FjZXJ0byRwX25hdGl2YV9yZXB0aWwsCiAgICAgICAgICAgICAgICAgICJSw6lwdGVpcyIsIHkgPSAiIiksIAogICAgbmNvbCA9IDUsCiAgICB0b3AgPSB0ZXh0R3JvYigiTml2ZWlzIGRlIHJlY29uaGVjaW1lbnRvIHBvciBvcmlnZW1cbiIsIAogICAgICAgICAgICAgICAgICAgZ3AgPSBncGFyKGZvbnRzaXplID0gMjAsIGZvbnQgPSAyKSksCiAgICByaWdodCA9ICJcbiIKKQpgYGAKCk1lZGluZG8gYXMgbcOpZGlhcyBkZSBhY2VydG8gbmEgaWRlbnRpZmljYcOnw6NvIGRvIG5vbWUgZGFzIGVzcMOpY2llcwoKYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Mn0KYmFycGxvdCh0YXBwbHkoCiAgICBwb3NfZ2FiYXJpdG8kcGVyY2VudHVhbF9hY2VydG8kcF9pbmRpY2VfZXhvdGljYXMsIAogICAgcG9zX2dhYmFyaXRvJHBlcmNlbnR1YWxfYWNlcnRvJHR1cm1hcywKICAgIG1lYW4pLCBtYWluID0gIk3DqWRpYSBkZSBpZGVudGlmaWNhw6fDo28gZG8gbm9tZSBkZSBvcmlnZW0gZXjDs3RpY2FzIHBvciB0dXJtYXMiKQpgYGAKYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Mn0KYmFycGxvdCh0YXBwbHkoCiAgICBwb3NfZ2FiYXJpdG8kcGVyY2VudHVhbF9hY2VydG8kcF9pbmRpY2VfbmF0aXZhcywgCiAgICBwb3NfZ2FiYXJpdG8kcGVyY2VudHVhbF9hY2VydG8kdHVybWFzLAogICAgbWVhbiksIG1haW4gPSAiTcOpZGlhIGRlIGlkZW50aWZpY2HDp8OjbyBkbyBub21lIGRlIG9yaWdlbSBuYXRpdmFzIHBvciB0dXJtYXMiKQpgYGAKCgojIyMgVGVzdGUgZGUgbm9ybWFsaWRhZGUKClBhcmEgZGV0ZXJtaW5hciBhIG5vcm1hbGlkYWRlIG5hcyBkaXN0cmlidWnDp29lcyBkYXMgcmVzcG9zdGFzIGRvIGpvZ28gZGUgaW1hZ2Vucy4KCmBgYHtyLCBlY2hvPUZBTFNFfQpncmFmaWNvX2RlbnNpZGFkZSA8LSBmdW5jdGlvbih2YXJpYXZlbCwgY29yLCB0aXR1bG8pIHsKICAgIHBsb3QgPC0gCiAgICAgICAgcG9zX2dhYmFyaXRvJHByb3BvcmNvZXMkcG9yX3R1cm1hICU+JSAKICAgICAgICBnZ2RlbnNpdHkoeCA9IHZhcmlhdmVsLCBmaWxsID0gY29yLAogICAgICAgICAgbWFpbiA9IHRpdHVsbywKICAgICAgICAgIHhsYWIgPSAiUGVyY2VudHVhbCBkZSBhY2VydG9zIikgKyAKICAgICAgICB4bGltKDAsIDEpICsgCiAgICAgICAgeWxpbSgwLCA4KQogICAgbm9tYWxpZGFkZSA8LSAKICAgICAgICBnZ3RleHR0YWJsZSgKICAgICAgICAgICAgbm9ybWFsaWRhZGUocG9zX2dhYmFyaXRvJHByb3BvcmNvZXMkcG9yX3R1cm1hW1t2YXJpYXZlbF1dKSwgCiAgICAgICAgICAgIHJvd3MgPSBOVUxMLCB0aGVtZSA9IHR0aGVtZShiYXNlX3N0eWxlID0gIm1PcmFuZ2UiLCBiYXNlX3NpemUgPSA4KQogICAgICAgICkKICAgIAogICAgcmVzdWx0YWRvIDwtIGxpc3QoCiAgICAgICAgcGxvdCA9IHBsb3QsCiAgICAgICAgbm9ybWFsaWRhZGUgPSBub21hbGlkYWRlCiAgICApCiAgICByZXR1cm4ocmVzdWx0YWRvKQp9Cgp0MSA8LSBncmFmaWNvX2RlbnNpZGFkZSgicF9uYXRpdmFzIiwgImdyZWVuIiwgIklkZW50aWZpY2HDp8OjbyBkbyBub21lIGRhcyBlc3DDqWNpZXMgZGUgb3JpZ2VtIE5hdGl2YXMiKQp0MiA8LSBncmFmaWNvX2RlbnNpZGFkZSgicF9leG90aWNhcyIsICJyZWQiLCAiSWRlbnRpZmljYcOnw6NvIGRvIG5vbWUgZGFzIGVzcMOpY2llcyBkZSBvcmlnZW0gRXjDs3RpY2FzIikKdDMgPC0gZ3JhZmljb19kZW5zaWRhZGUoInBfb3JpZ2VtX25hdGl2YXMiLCAiZGFya2dyZWVuIiwgIklkZW50aWZpY2HDp8OjbyBkZSBvcmlnZW0gTmF0aXZhcyIpCnQ0IDwtIGdyYWZpY29fZGVuc2lkYWRlKCJwX29yaWdlbV9leG90aWNhcyIsICJkYXJrcmVkIiwgIklkZW50aWZpY2HDp8OjbyBkZSBvcmlnZW0gRXjDs3RpY2FzIikKdDUgPC0gZ3JhZmljb19kZW5zaWRhZGUoInBfaW5kaWNlX25hdGl2YXMiLCAib3JhbmdlIiwgIkluZGljZSBkZSByZWNvbmhlY2ltZW50byBOYXRpdmFzIChvcmlnZW5zICsgZXNww6ljaWVzKSIpCnQ2IDwtIGdyYWZpY29fZGVuc2lkYWRlKCJwX2luZGljZV9leG90aWNhcyIsICJvcmFuZ2VyZWQiLCAiSW5kaWNlIGRlIHJlY29uaGVjaW1lbnRvIEV4w7N0aWNhcyAob3JpZ2VucyArIGVzcMOpY2llcykiKQpgYGAKCiMjIyMgSWRlbnRpZmljYcOnw6NvIG3DqWRpbyBkYXMgdHVybWFzIChub21lcyBkYXMgZXNww6ljaWVzICYgb3JpZ2VucykKCmBgYHtyIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTV9CmdyaWQuYXJyYW5nZSh0MSRwbG90LCB0MiRwbG90LAogICAgICAgICAgICAgdDEkbm9ybWFsaWRhZGUsIHQyJG5vcm1hbGlkYWRlLAogICAgICAgICAgICAgdDMkcGxvdCwgdDQkcGxvdCwKICAgICAgICAgICAgIHQzJG5vcm1hbGlkYWRlLCB0NCRub3JtYWxpZGFkZSwKICAgICAgICAgICAgIG5jb2wgPSAyLAogICAgICAgICAgICAgaGVpZ2h0cyA9IGMoMywyLDMsMiksCiAgICAgICAgICAgICB0b3AgPSB0ZXh0R3JvYigiRGVuc2lkYWRlIGRlIGlkZW50aWZpY2HDp8OjbyBtw6lkaWEgZGFzIHR1cm1hcyBlbnRyZSBcbmVzcGVjaWVzIGUgc3VhcyBvcmlnZW5zXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3AgPSBncGFyKGZvbnRzaXplID0gMjAsIGZvbnQgPSAyKSkKICAgICAgICAgICAgICkKYGBgCgojIyMjIEluZGljZSBkZSByZWNvbmhlY2ltZW50byBtw6lkaW8gZGFzIHR1cm1hcwoKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9M30KZ3JpZC5hcnJhbmdlKHQ1JHBsb3QsIHQ2JHBsb3QsCiAgICAgICAgICAgICB0NSRub3JtYWxpZGFkZSwgdDYkbm9ybWFsaWRhZGUsCiAgICAgICAgICAgICBuY29sID0gMiwKICAgICAgICAgICAgIGhlaWdodHMgPSBjKDQsMyksCiAgICAgICAgICAgICB0b3AgPSB0ZXh0R3JvYigiRGVuc2lkYWRlIGRvcyBpbmRpY2VzIGRlIHJlY29uaGVjaW1lbnRvIG3DqWRpbyBkYXMgdHVybWFzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3AgPSBncGFyKGZvbnRzaXplID0gMjAsIGZvbnQgPSAyKSkKICAgICAgICAgICAgICkKYGBgCgoKIyMjIFEtUSBUZXN0CgpgYGB7ciwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0KcXFwbG90LmRhdGEgPC0gZnVuY3Rpb24gKHZlYywgdGl0dWxvKSB7CiAgIyBmb2xsb3dpbmcgZm91ciBsaW5lcyBmcm9tIGJhc2UgUidzIHFxbGluZSgpCiAgeSA8LSBxdWFudGlsZSh2ZWNbIWlzLm5hKHZlYyldLCBjKDAuMjUsIDAuNzUpKQogIHggPC0gcW5vcm0oYygwLjI1LCAwLjc1KSkKICBzbG9wZSA8LSBkaWZmKHkpL2RpZmYoeCkKICBpbnQgPC0geVsxTF0gLSBzbG9wZSAqIHhbMUxdCgogIGQgPC0gZGF0YS5mcmFtZShyZXNpZHMgPSB2ZWMpCgogIGdncGxvdChkLCBhZXMoc2FtcGxlID0gcmVzaWRzKSkgKyAKICAgICAgc3RhdF9xcSgpICsgCiAgICAgIGdlb21fYWJsaW5lKHNsb3BlID0gc2xvcGUsIGludGVyY2VwdCA9IGludCwgY29sID0gInJlZCIpICsKICAgICAgeGxpbSgtMiwgMikgKwogICAgICB5bGltKDAsIDEpICsKICAgICAgdGhlbWVfYncoKSArCiAgICAgIGxhYnMoCiAgICAgICAgdGl0bGUgPSB0aXR1bG8KICAgICkKfQoKcTEgPC0gcXFwbG90LmRhdGEocG9zX2dhYmFyaXRvJHByb3BvcmNvZXMkcG9yX3R1cm1hJHBfbmF0aXZhcywgIklkZW50aWZpY2HDp8OjbyBkbyBub21lIGRhcyBlc3DDqWNpZXMgZGUgb3JpZ2VtIE5hdGl2YXMiKQpxMiA8LSBxcXBsb3QuZGF0YShwb3NfZ2FiYXJpdG8kcHJvcG9yY29lcyRwb3JfdHVybWEkcF9leG90aWNhcywgIklkZW50aWZpY2HDp8OjbyBkbyBub21lIGRhcyBlc3DDqWNpZXMgZGUgb3JpZ2VtIEV4b3RpY2FzIikKcTMgPC0gcXFwbG90LmRhdGEocG9zX2dhYmFyaXRvJHByb3BvcmNvZXMkcG9yX3R1cm1hJHBfb3JpZ2VtX25hdGl2YXMsICJJZGVudGlmaWNhw6fDo28gZGUgb3JpZ2VtIE5hdGl2YXMiKQpxNCA8LSBxcXBsb3QuZGF0YShwb3NfZ2FiYXJpdG8kcHJvcG9yY29lcyRwb3JfdHVybWEkcF9vcmlnZW1fZXhvdGljYXMsICJJZGVudGlmaWNhw6fDo28gZGUgb3JpZ2VtIEV4b3RpY2FzIikKcTUgPC0gcXFwbG90LmRhdGEocG9zX2dhYmFyaXRvJHByb3BvcmNvZXMkcG9yX3R1cm1hJHBfaW5kaWNlX25hdGl2YXMsICJJbmRpY2UgZGUgcmVjb25oZWNpbWVudG8gTmF0aXZhcyAob3JpZ2VucyArIGVzcMOpY2llcykiKQpxNiA8LSBxcXBsb3QuZGF0YShwb3NfZ2FiYXJpdG8kcHJvcG9yY29lcyRwb3JfdHVybWEkcF9pbmRpY2VfZXhvdGljYXMsICJJbmRpY2UgZGUgcmVjb25oZWNpbWVudG8gRXhvdGljYXMgKG9yaWdlbnMgKyBlc3DDqWNpZXMpIikKCmdyaWQuYXJyYW5nZShxMSwgcTIsIAogICAgICAgICAgICAgcTMsIHE0LAogICAgICAgICAgICAgcTUsIHE2LAogICAgICAgICAgICAgbmNvbCA9IDIsCiAgICAgICAgICAgICB0b3AgPSB0ZXh0R3JvYigiTm9ybWFsIFEtUSBQbG90XG4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdwID0gZ3Bhcihmb250c2l6ZSA9IDIwLCBmb250ID0gMikpCiAgICAgICAgICAgICApCmBgYAoKIyMjIFRlc3RlIGRlIHZhcmnDom5jaWEKClBhcmEgZGV0ZXJtaW5hciBhIHZhcmnDom5jaWEKCmBgYHtyfQp2YXJpYW5jaWEgPC0gZGF0YS5mcmFtZSgKICAgIEFsZ29yaXRtbyA9IGMoIkYgdGVzdCB0byBjb21wYXJlIHR3byB2YXJpYW5jZXMiKSwKICAgICJDb21wYXJhw6fDo28iID0gYygiTmF0aXZhcyB4IEV4w7N0aWNhcyIpLAogICAgIlZhcmnDoXZlbCIgPSBjKAogICAgICAgICJJbmRpY2UgZGUgcmVjb25oZWNpbWVudG8iLAogICAgICAgICJJZGVudGlmaWNhw6fDo28gZG8gbm9tZSBkYXMgZXNww6ljaWVzIiwKICAgICAgICAiSWRlbnRpZmljYcOnw6NvIGRhIG9yaWdlbSIKICAgICksCiAgICAicF92YWxvciIgPSBjKAogICAgICAgIHZhci50ZXN0KHBvc19nYWJhcml0byRwcm9wb3Jjb2VzJHBvcl90dXJtYSRwX2luZGljZV9uYXRpdmFzLCAKICAgICAgICAgICAgICAgICBwb3NfZ2FiYXJpdG8kcHJvcG9yY29lcyRwb3JfdHVybWEkcF9pbmRpY2VfZXhvdGljYXMsIAogICAgICAgICAgICAgICAgIGFsdGVybmF0aXZlID0gInR3by5zaWRlZCIpJHAudmFsdWUsCiAgICAgICAgdmFyLnRlc3QocG9zX2dhYmFyaXRvJHByb3BvcmNvZXMkcG9yX3R1cm1hJHBfbmF0aXZhcywgCiAgICAgICAgICAgICAgICAgcG9zX2dhYmFyaXRvJHByb3BvcmNvZXMkcG9yX3R1cm1hJHBfZXhvdGljYXMsIAogICAgICAgICAgICAgICAgIGFsdGVybmF0aXZlID0gInR3by5zaWRlZCIpJHAudmFsdWUsCiAgICAgICAgdmFyLnRlc3QocG9zX2dhYmFyaXRvJHByb3BvcmNvZXMkcG9yX3R1cm1hJHBfb3JpZ2VtX25hdGl2YXMsIAogICAgICAgICAgICAgICAgIHBvc19nYWJhcml0byRwcm9wb3Jjb2VzJHBvcl90dXJtYSRwX29yaWdlbV9leG90aWNhcywgCiAgICAgICAgICAgICAgICAgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIikkcC52YWx1ZQogICAgKQopCgp2YXJpYW5jaWEgPC0gdmFyaWFuY2lhICU+JQogICAgbXV0YXRlKAogICAgICAgIHZhcmlhbmNpYSA9IHBfdmFsb3IgPiAwLjA1LAogICAgICAgIHBfdmFsb3IgPSBjZWxsX3NwZWMocm91bmQocF92YWxvciwgNCksIGJvbGQgPSBULCBjb2xvciA9ICJibGFjayIsIGFsaWduID0gInJpZ2h0IiksCiAgICAgICAgdmFyaWFuY2lhID0gY2VsbF9zcGVjKHZhcmlhbmNpYSwgYm9sZCA9IHZhcmlhbmNpYSwKICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj0gaWZlbHNlKHZhcmlhbmNpYSwgIndoaXRlIiwgImJsYWNrIiksIAogICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmQgPSBpZmVsc2UodmFyaWFuY2lhLCAiZ3JlZW4iLCAiI0NDQ0NDQyIpKQogICAgKQoKdmFyaWFuY2lhICU+JQogIGthYmxlKGVzY2FwZSA9IEYpICU+JQogIGthYmxlX3N0eWxpbmcoYygic3RyaXBlZCIsICJib3JkZXJlZCIpLCBmdWxsX3dpZHRoID0gVFJVRSkgJT4lCiAgY29sdW1uX3NwZWMoMSwgYm9sZCA9IFRSVUUpICU+JQogIGNvbGxhcHNlX3Jvd3MoY29sdW1ucyA9IDE6MiwgdmFsaWduID0gInRvcCIpIApgYGAKCiMjIyBBbmFsaXNlcyBkZXNjcml0aXZhcwoKYGBge3J9CmhlYWQocG9zX2dhYmFyaXRvJGVzcGVjaWVzLCAxMCkKYGBgCgojIyMjIEluZGljZSBkZSBpZGVudGlmaWNhw6fDo28gcG9yIE9yaWdlbQoKYGBge3IsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTZ9CnBvc19nYWJhcml0byRlc3BlY2llcyAlPiUgCiAgICBnZ3Bsb3QoYWVzKGVzcGVjaWVEZXNjLCBmciwgZmlsbCA9IGdydXBvKSkgKyAKICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKwogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChyb3VuZChmciAqIDEwMCwgMSksICIlIikpLCAKICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksIHZqdXN0ID0gMC41LAogICAgICAgICAgICAgIGhqdXN0ID0gLTAuNSkgKwogICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwxLjIpLCBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsKICAgIGZhY2V0X3dyYXAofm9yaWdlbSwgc2NhbGVzID0gImZyZWVfeSIpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICB0aGVtZV9idygpICsKICAgIGxhYnModGl0bGUgPSAiSW5kaWNlIGRlIElkZW50aWZpY2HDp8OjbyBwb3IgT3JpZ2VtIiwKICAgICAgICAgZmlsbCA9ICJHcnVwb3MiLCB4ID0gIiIsIHkgPSAiXG5GcmVxdWVuY2lhIHJlbGF0aXZhIikgKwogICAgbXlfdGhlbWUKYGBgCgojIyMjIEluZGljZSBkZSBpZGVudGlmaWNhw6fDo28gcG9yIEVzcMOpY2llCgpgYGB7ciwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0KcG9zX2dhYmFyaXRvJGVzcGVjaWVzICU+JSAKICAgIGdncGxvdChhZXMoZXNwZWNpZURlc2MsIGZyLCBmaWxsID0gb3JpZ2VtKSkgKyAKICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKwogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChyb3VuZChmciAqIDEwMCwgMSksICIlIikpLCAKICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksIHZqdXN0ID0gMC41LAogICAgICAgICAgICAgIGhqdXN0ID0gLTAuMykgKwogICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwxLjIpLCBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsKICAgIGZhY2V0X3dyYXAofmdydXBvLCBzY2FsZXMgPSAiZnJlZV95IikgKwogICAgY29vcmRfZmxpcCgpICsKICAgIHRoZW1lX2J3KCkgKwogICAgbGFicyh0aXRsZSA9ICJJbmRpY2UgZGUgSWRlbnRpZmljYcOnw6NvIHBvciBFc3DDqWNpZSIsCiAgICAgICAgIGZpbGwgPSAiT3JpZ2VtIiwgeCA9ICIiLCB5ID0gIlxuRnJlcXVlbmNpYSByZWxhdGl2YSIpICsKICAgIG15X3RoZW1lCmBgYAoKIyMgVGVzdGVzIGRlIGhpcG90ZXNlcwoKRXNwZXJhZG8gcC12YWxvciA+PSAwLjA1IG5hIG5vcm1hbGlkYWRlIChlc3BlcmEtc2UgSDApCkVzcGVyYWRvIHAtdmFsb3IgPD0gMC4wNSBubyB0ZXN0ZSBkZSBoaXBvdGVzZSAoZXNwZXJhLXNlIEgxKQoKVGFiZWxhIGRvcyB0ZXN0ZXMgZGUgaGlwb3Rlc2VzIGFwbGljYWRvcwoKYGBge3J9CnQxIDwtIHQudGVzdCgKICAgcG9zX2dhYmFyaXRvJHBlcmNlbnR1YWxfYWNlcnRvJHBfbm9tZV9leG90aWNhcywgCiAgIHBvc19nYWJhcml0byRwZXJjZW50dWFsX2FjZXJ0byRwX25vbWVfbmF0aXZhcywgCiAgIGFsdGVybmF0aXZlID0gInR3by5zaWRlZCIsIHBhaXJlZCA9IFRSVUUsIGNvbmYubGV2ZWwgPSAuOTUpCnQyIDwtIHQudGVzdCgKICAgcG9zX2dhYmFyaXRvJHBlcmNlbnR1YWxfYWNlcnRvJHBfb3JpZ2VtX2V4b3RpY2FzLCAKICAgcG9zX2dhYmFyaXRvJHBlcmNlbnR1YWxfYWNlcnRvJHBfb3JpZ2VtX25hdGl2YXMsIAogICBhbHRlcm5hdGl2ZSA9ICJ0d28uc2lkZWQiLCBwYWlyZWQgPSBUUlVFLCBjb25mLmxldmVsID0gLjk1KQp0MyA8LSB0LnRlc3QoCiAgIHBvc19nYWJhcml0byRwZXJjZW50dWFsX2FjZXJ0byRwX2luZGljZV9leG90aWNhcywgCiAgIHBvc19nYWJhcml0byRwZXJjZW50dWFsX2FjZXJ0byRwX2luZGljZV9uYXRpdmFzLCAKICAgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIiwgcGFpcmVkID0gVFJVRSwgY29uZi5sZXZlbCA9IC45NSkKCmRhdGEuZnJhbWUoCiAgICBBbGdvcml0bW8gPSBjKHQxJG1ldGhvZCwgdDIkbWV0aG9kLCB0MyRtZXRob2QpLAogICAgIkNvbXBhcmHDp8OjbyIgPSBjKCJFeMOzdGljYXMgeCBOYXRpdmFzIiksCiAgICAiVmFyacOhdmVsIiA9IGMoCiAgICAgICAgIklkZW50aWZpY2HDp8OjbyBkbyBub21lIGRhcyBlc3DDqWNpZXMiLAogICAgICAgICJJZGVudGlmaWNhw6fDo28gZGEgb3JpZ2VtIiwKICAgICAgICAiSW5kaWNlIGRlIHJlY29uaGVjaW1lbnRvIgogICAgKSwKICAgIHBfdmFsb3IgPSBjKHQxJHAudmFsdWUsIHQyJHAudmFsdWUsIHQzJHAudmFsdWUpLAogICAgSDAgPSBjKHQxJHAudmFsdWUgPj0gMC4wNSwgdDIkcC52YWx1ZSA+PSAwLjA1LCB0MyRwLnZhbHVlID49IDAuMDUpLAogICAgSDEgPSBjKHQxJHAudmFsdWUgPCAwLjA1LCB0MiRwLnZhbHVlIDwgMC4wNSwgdDMkcC52YWx1ZSA8IDAuMDUpLAogICAgIkNvbmZpYW7Dp2EiID0gYygKICAgICAgICBwYXN0ZShwYXN0ZTAocm91bmQodDEkY29uZi5pbnQgKiAxMDAsIDIpLCAiJSIpLCBjb2xsYXBzZSA9ICIgfiAiKSwKICAgICAgICBwYXN0ZShwYXN0ZTAocm91bmQodDIkY29uZi5pbnQgKiAxMDAsIDIpLCAiJSIpLCBjb2xsYXBzZSA9ICIgfiAiKSwKICAgICAgICBwYXN0ZShwYXN0ZTAocm91bmQodDMkY29uZi5pbnQgKiAxMDAsIDIpLCAiJSIpLCBjb2xsYXBzZSA9ICIgfiAiKQogICAgKQopICU+JQogIG11dGF0ZSgKICAgIHBfdmFsb3IgPSBjZWxsX3NwZWMocF92YWxvciwgYm9sZCA9IFQsIGNvbG9yID0gImJsYWNrIiwgYWxpZ24gPSAicmlnaHQiKSwKICAgIEgwID0gY2VsbF9zcGVjKEgwLCBib2xkID0gSDAsCiAgICAgICAgICAgICAgICAgICBjb2xvcj0gaWZlbHNlKEgwLCAid2hpdGUiLCAiYmxhY2siKSwgCiAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kID0gaWZlbHNlKEgwLCAiZ3JlZW4iLCAiI0NDQ0NDQyIpKSwKICAgIEgxID0gY2VsbF9zcGVjKEgxLCBib2xkID0gSDEsIAogICAgICAgICAgICAgICAgICAgY29sb3IgPSBpZmVsc2UoSDEsICJ3aGl0ZSIsICJibGFjayIpLCAKICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmQgPSBpZmVsc2UoSDEsICJncmVlbiIsICIjQ0NDQ0NDIikpCiAgKSAlPiUKICBrYWJsZShlc2NhcGUgPSBGKSAlPiUKICBrYWJsZV9zdHlsaW5nKGMoInN0cmlwZWQiLCAiYm9yZGVyZWQiKSwgZnVsbF93aWR0aCA9IFRSVUUpICU+JQogIGNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUUlVFKSAlPiUKICBjb2xsYXBzZV9yb3dzKGNvbHVtbnMgPSAxOjIsIHZhbGlnbiA9ICJ0b3AiKSAlPiUKICBmb290bm90ZShnZW5lcmFsID0gIkludGVydmFsbyBkZSBjb25maWFuw6dhIDk1JSIsCiAgICAgICAgICAgZ2VuZXJhbF90aXRsZSA9ICJcbk9icy46ICIsCiAgICAgICAgICAgZm9vdG5vdGVfYXNfY2h1bmsgPSBUKQpgYGAKCgojIyMgMSAtIE9zIGFsdW5vcyBpdGVuZGlmaWNhbSBtYWlzIG9zIG5vbWVzIGRvcyBhbmltYWlzIGRlIGVzcMOpY2llcyBleMOzdGljYXMgcXVlIG9zIGFuaW1haXMgZGUgZXNww6ljaWVzIG5hdGl2YXMuCgpgYGB7ciwgZWNobz1GQUxTRX0KdDEKYGBgCgoKIyMjIDIgLSBPcyBhbHVub3MgaWRlbnRpZmljYW0gbWFpcyBlc3DDqWNpZXMgZGUgb3JpZ2VtIGV4w7N0aWNhIHF1ZSBhcyBkZSBvcmlnZW0gbmF0aXZhLgoKYGBge3IsIGVjaG89RkFMU0V9CnQyCmBgYAoKIyMjIDMgLSBPcyBhbHVub3MgaWRlbnRpZmljYW0gbWFpcyBhcyBlc3DDqWNpZXMgZXjDs3RpY2FzIChub21lIGRvcyBhbmltYWlzIGUgb3JpZ2VtKSBxdWUgZXNww6ljaWVzIG5hdGl2YXMuCgpgYGB7ciwgZWNobz1GQUxTRX0KdDMKYGBgCgojIyMgNCAtIE9zIGFsdW5vcyByZWNvbmhlY2VtIG1haXMgbWFtw61mZXJvcyBkbyBxdWUgb3MgZGVtYWlzIGdydXBvcyB0YXhvbsOzbWljb3MuCgpgYGB7ciwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9M30KcG9zX2dhYmFyaXRvJHRheG9ub21pY29zICU+JQogICAgZ2dwbG90KCkgKyAKICAgIGdlb21fYm94cGxvdChhZXMoeCA9IGdydXBvLCB5ID0gdmFsdWUsIGZpbGwgPSBvcmlnZW0pLCBzaG93LmxlZ2VuZCA9IFQpICsgCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEpLCBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsKICAgIHRoZW1lX2J3KCkgKwogICAgbGFicyh0aXRsZSA9ICJCb3hwbG90IGRlIGlkZW50aWZpY2HDp8OjbyBkZSBlc3DDqWNpZXMgcG9yIGdydXBvIHRheG9uw7RtaWNvIiwKICAgICAgICAgeSA9ICJQZXJjZW50dWFsIGRlIGlkZW50aWZpY2HDp8OjbyIsIHggPSAiIikgKwogICAgbXlfdGhlbWUKYGBgCgpgYGB7cn0KdG1wIDwtIHBvc19nYWJhcml0byRwZXJjZW50dWFsX2FjZXJ0byAlPiUKICAgIHNlbGVjdChwX2V4b3RpY2FfYXZlczpwX25hdGl2YV9yZXB0aWwpICU+JQogICAgbWVsdCgpCgp0bXAgPC0gY2JpbmQodG1wLCBjb2xzcGxpdCh0bXAkdmFyaWFibGUsICJfIiwgYygicCIsICJpbmRpY2Fkb3IiLCAib3JpZ2VtIikpKSAlPiUKICAgIHNlbGVjdChpbmRpY2Fkb3IsIG9yaWdlbSwgdmFsdWUpCgphbm92YShsbSh2YWx1ZSB+IGluZGljYWRvciAqIG9yaWdlbSwgdG1wKSkKVHVrZXlIU0QoYW92KGxtKHZhbHVlIH4gaW5kaWNhZG9yICogb3JpZ2VtLCB0bXApKSkKYGBgCgoKYGBge3IsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTV9CiMgUmVhbGl6YW5kbyBBbm92YSBmYXRvcmlhbAphbm92YShsbSh2YWx1ZSB+IGdydXBvICogb3JpZ2VtLCBwb3NfZ2FiYXJpdG8kdGF4b25vbWljb3MpKQpUdWtleUhTRChhb3YobG0odmFsdWUgfiBncnVwbyAqIG9yaWdlbSwgcG9zX2dhYmFyaXRvJHRheG9ub21pY29zKSkpCmBgYAoKIyMjIDUgLSBFc3R1ZGFudGVzIHF1ZSByZXNpZGVtIG5hIENpZGFkZSAxIChjb20gVUMpIGlkZW50aWZpY2FtIG1haXMgZXNww6ljaWVzIG5hdGl2YXMgZG8gcXVlIGVzdHVkYW50ZXMgcXVlIHJlc2lkZW0gbmEgQ2lkYWRlIDIgKHNlbSBVQykuCgpgYGB7ciwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9M30KdG1wIDwtCiAgICBtZXJnZSgKICAgICAgICBwb3NfZ2FiYXJpdG8kZGFkb3MgJT4lIAogICAgICAgICAgICBzZWxlY3QodHVybWFzLCBtdW5pY2lwaW8pICU+JSAKICAgICAgICAgICAgdW5pcXVlKCksCiAgICAgICAgcG9zX2dhYmFyaXRvJHByb3BvcmNvZXMkcG9yX3R1cm1hX2FyZWEKICAgICkgJT4lCiAgICBzZWxlY3QobXVuaWNpcGlvLCBhcmVhLCB2YWx1ZSA9IHBfbmF0aXZhcykgJT4lCiAgICB0YmxfZGYoKQoKIyBSZWFsaXphbmRvIG8gdGVzdGUgVAp0LnRlc3QodmFsdWUgfiBtdW5pY2lwaW8sIHRtcCkKYGBgCgpgYGB7ciwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9M30KdG1wICU+JQogIGdncGxvdCgpICsgCiAgZ2VvbV9ib3hwbG90KGFlcyh4ID0gYXJlYSwgeSA9IHZhbHVlLCBmaWxsID0gbXVuaWNpcGlvKSwgc2hvdy5sZWdlbmQgPSBUKSArIAogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsMSksIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkgKwogIGZhY2V0X3dyYXAofm11bmljaXBpbykgKwogIHRoZW1lX2J3KCkgKwogIGxhYnModGl0bGUgPSAiQm94cGxvdCBkZSBpZGVudGlmaWNhw6fDo28gZGUgZXNww6ljaWVzIE5hdGl2YXMgbm9zIGNyaXTDqXJpb3MgZXN0YWJlbGVjaWRvcyIsCiAgICAgICB5ID0gIlBlcmNlbnR1YWwgZGUgaWRlbnRpZmljYcOnw6NvIiwgeCA9ICIiKSArCiAgbXlfdGhlbWUKCmBgYAoKIyMjIDYgLSBFc3R1ZGFudGVzIHF1ZSByZXNpZGVtIGVtIMOhcmVhIHJ1cmFsIHRlbSBtYWlvciBjb25oZWNpbWVudG8gc29icmUgYXMgZXNww6ljaWVzIG5hdGl2YXMuCgpgYGB7ciwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9M30KdG1wIDwtIAogICAgcG9zX2dhYmFyaXRvJHByb3BvcmNvZXMkcG9yX3R1cm1hX2FyZWEgJT4lCiAgICBzZWxlY3QobXVuaWNpcGlvLCBhcmVhLCBwX25vbWVfbmF0aXZhcyA9IHBfbmF0aXZhcywgcF9vcmlnZW1fbmF0aXZhcywgcF9pbmRpY2VfbmF0aXZhcykgJT4lCiAgICBhcnJhbmdlKGFyZWEpICU+JQogICAgbWVsdChpZCA9IGMoIm11bmljaXBpbyIsICJhcmVhIikpCgp0bXAgPC0KICAgIGNiaW5kKHRtcCwgY29sc3BsaXQodG1wJHZhcmlhYmxlLCAiXyIsIGMoInAiLCAiaW5kaWNhZG9yIiwgIm9yaWdlbSIpKSkgJT4lCiAgICBzZWxlY3QobXVuaWNpcGlvLCBhcmVhLCBpbmRpY2Fkb3IsIG9yaWdlbSwgdmFsdWUpCgp0bXAgJT4lCiAgZ2dwbG90KCkgKyAKICBnZW9tX2JveHBsb3QoYWVzKHggPSBhcmVhLCB5ID0gdmFsdWUsIGZpbGwgPSBtdW5pY2lwaW8pLCBzaG93LmxlZ2VuZCA9IFQpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwxKSwgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSArCiAgZmFjZXRfd3JhcCh+aW5kaWNhZG9yKSArCiAgdGhlbWVfYncoKSArCiAgbGFicyh0aXRsZSA9ICJCb3hwbG90IGRlIGlkZW50aWZpY2HDp8OjbyBkZSBlc3DDqWNpZXMgTmF0aXZhcyBub3MgY3JpdMOpcmlvcyBlc3RhYmVsZWNpZG9zIiwKICAgICAgIHkgPSAiUGVyY2VudHVhbCBkZSBpZGVudGlmaWNhw6fDo28iLCB4ID0gIiIpICsKICBteV90aGVtZQpgYGAKCmBgYHtyfQojYm94cGxvdCh2YWx1ZSAgfiBtdW5pY2lwaW8gKyBhcmVhLCBkYXRhID0gdG1wKQojIGludGVyYWN0aW9uLnBsb3QodG1wJGFyZWEsIHRtcCRtdW5pY2lwaW8sIHRtcCR2YWx1ZSkKIyBpbnRlcmFjdGlvbi5wbG90KHRtcCRtdW5pY2lwaW8sIHRtcCRhcmVhLCB0bXAkdmFsdWUpCiMgYWdncmVnYXRlKHZhbHVlIH4gYXJlYSAqIG11bmljaXBpbywgZGF0YSA9IHRtcCwgRlVOID0gZnVuY3Rpb24oeCkgc2hhcGlyby50ZXN0KHgpJHAudmFsdWUpCiMgdG1wJGJhcnQgPSBwYXN0ZSh0bXAkbXVuaWNpcGlvLCAiLSIsIHRtcCRhcmVhKQojIGJhcnRsZXR0LnRlc3QodmFsdWUgfiBiYXJ0LCBkYXRhID0gdG1wKQoKdC5hbm92YSA8LSBhbm92YShsbSh2YWx1ZSAgfiBtdW5pY2lwaW8gKiBhcmVhLCBkYXRhID0gdG1wICU+JSBmaWx0ZXIoaW5kaWNhZG9yID09ICJpbmRpY2UiKSkpCnQuYW5vdmEgJT4lCiAgICBrYWJsZSgpICU+JQogICAga2FibGVfc3R5bGluZyhjKCJzdHJpcGVkIiwgImJvcmRlcmVkIiksIGZ1bGxfd2lkdGggPSBUUlVFKSAlPiUKICAgIGNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUUlVFKQoKdHVrZXkgPC0gVHVrZXlIU0QoYW92KGxtKHZhbHVlICB+IG11bmljaXBpbyAqIGFyZWEsIGRhdGEgPSB0bXAgJT4lIGZpbHRlcihpbmRpY2Fkb3IgPT0gImluZGljZSIpKSkpCnR1a2V5CiNwbG90KHR1a2V5KQoKdGsgPC0gYXMuZGF0YS5mcmFtZSh0dWtleSRgbXVuaWNpcGlvOmFyZWFgKQp0ayRjb21wYXJhY2FvID0gcm93bmFtZXModGspCnJvd25hbWVzKHRrKSA9IE5VTEwKdGsgJT4lCiAgICBzZWxlY3QoY29tcGFyYWNhbywgZGlmZjpgcCBhZGpgKSAlPiUKICAgIG11dGF0ZShzaWduaWZpY2FuY2lhID0gYHAgYWRqYCA8PSAwLjA1KSAlPiUKICAgIGthYmxlKCkgJT4lCiAgICBrYWJsZV9zdHlsaW5nKGMoInN0cmlwZWQiLCAiYm9yZGVyZWQiKSwgZnVsbF93aWR0aCA9IFRSVUUpICU+JQogICAgY29sdW1uX3NwZWMoMSwgYm9sZCA9IFRSVUUpCgpgYGAKCiMjIyA3IC0gRnJlcXVlbmNpYSBkZSBjb250YXRvIG5hdHVyZXphCgpgYGB7ciwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9M30KdG1wIDwtIAogICAgcG9zX2dhYmFyaXRvJHByb3BvcmNvZXMkcG9yX3R1cm1hX2ZyZXFfY29udGF0byAlPiUKICAgIHNlbGVjdChmcmVxdWVuY2lhLCBwX25vbWVfbmF0aXZhcyA9IHBfbmF0aXZhcywgcF9vcmlnZW1fbmF0aXZhcywgcF9pbmRpY2VfbmF0aXZhcykgJT4lCiAgICBhcnJhbmdlKGZyZXF1ZW5jaWEpICU+JQogICAgbWVsdChpZCA9ICJmcmVxdWVuY2lhIikKCnRtcCA8LQogICAgY2JpbmQodG1wLCBjb2xzcGxpdCh0bXAkdmFyaWFibGUsICJfIiwgYygicCIsICJpbmRpY2Fkb3IiLCAib3JpZ2VtIikpKSAlPiUKICAgIHNlbGVjdChmcmVxdWVuY2lhLCBpbmRpY2Fkb3IsIG9yaWdlbSwgdmFsdWUpCgp0bXAgJT4lCiAgZ2dwbG90KCkgKyAKICBnZW9tX2JveHBsb3QoYWVzKHggPSBmcmVxdWVuY2lhLCB5ID0gdmFsdWUsIGZpbGwgPSBmcmVxdWVuY2lhKSwgc2hvdy5sZWdlbmQgPSBUKSArIAogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsMSksIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkgKwogIGZhY2V0X3dyYXAofmluZGljYWRvcikgKwogIHRoZW1lX2J3KCkgKwogIGxhYnModGl0bGUgPSAiQm94cGxvdCBkZSBpZGVudGlmaWNhw6fDo28gZGUgZXNww6ljaWVzIE5hdGl2YXMgbm9zIGNyaXTDqXJpb3MgZXN0YWJlbGVjaWRvcyIsCiAgICAgICB5ID0gIlBlcmNlbnR1YWwgZGUgaWRlbnRpZmljYcOnw6NvIiwgeCA9ICIiKSArCiAgbXlfdGhlbWUKYGBgCgpgYGB7cn0KIyBhZ2dyZWdhdGUodmFsdWUgfiBmcmVxdWVuY2lhLCAKIyAgICAgICAgICAgZGF0YSA9IHRtcCAlPiUgZmlsdGVyKGluZGljYWRvciA9PSAiaW5kaWNlIiksIAojICAgICAgICAgICBGVU4gPSBmdW5jdGlvbih4KSBzaGFwaXJvLnRlc3QoeCkkcC52YWx1ZSkKCnQuYW5vdmEgPC0gYW5vdmEobG0odmFsdWUgIH4gZnJlcXVlbmNpYSwgZGF0YSA9IHRtcCAlPiUgZmlsdGVyKGluZGljYWRvciA9PSAiaW5kaWNlIikpKQp0LmFub3ZhICU+JQogICAga2FibGUoKSAlPiUKICAgIGthYmxlX3N0eWxpbmcoYygic3RyaXBlZCIsICJib3JkZXJlZCIpLCBmdWxsX3dpZHRoID0gVFJVRSkgJT4lCiAgICBjb2x1bW5fc3BlYygxLCBib2xkID0gVFJVRSkKCnR1a2V5IDwtIFR1a2V5SFNEKGFvdihsbSh2YWx1ZSAgfiBmcmVxdWVuY2lhLCBkYXRhID0gdG1wICU+JSBmaWx0ZXIoaW5kaWNhZG9yID09ICJpbmRpY2UiKSkpKQp0dWtleQojcGxvdCh0dWtleSkKCnRrIDwtIGFzLmRhdGEuZnJhbWUodHVrZXkkZnJlcXVlbmNpYSkKdGskY29tcGFyYWNhbyA9IHJvd25hbWVzKHRrKQpyb3duYW1lcyh0aykgPSBOVUxMCnRrICU+JQogICAgc2VsZWN0KGNvbXBhcmFjYW8sIGRpZmY6YHAgYWRqYCkgJT4lCiAgICBtdXRhdGUoc2lnbmlmaWNhbmNpYSA9IGBwIGFkamAgPD0gMC4wNSkgJT4lCiAgICBrYWJsZSgpICU+JQogICAga2FibGVfc3R5bGluZyhjKCJzdHJpcGVkIiwgImJvcmRlcmVkIiksIGZ1bGxfd2lkdGggPSBUUlVFKSAlPiUKICAgIGNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUUlVFKQoKYGBgCgojIyMgOCAtIEZleiBhdWxhcyBwcmF0aWNhcwoKYGBge3IsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTN9CnRtcCA8LSAKICAgIHBvc19nYWJhcml0byRwcm9wb3Jjb2VzJHBvcl90dXJtYV9mZXpfYXVsYSAlPiUKICAgIHNlbGVjdChmZXouYXVsYSwgcF9ub21lX25hdGl2YXMgPSBwX25hdGl2YXMsIHBfb3JpZ2VtX25hdGl2YXMsIHBfaW5kaWNlX25hdGl2YXMpICU+JQogICAgYXJyYW5nZShmZXouYXVsYSkgJT4lCiAgICBtZWx0KGlkID0gImZlei5hdWxhIikKCnRtcCA8LSBjYmluZCh0bXAsIGNvbHNwbGl0KHRtcCR2YXJpYWJsZSwgIl8iLCBjKCJwIiwgImluZGljYWRvciIsICJvcmlnZW0iKSkpICU+JQogIHNlbGVjdChmZXouYXVsYSwgaW5kaWNhZG9yLCBvcmlnZW0sIHZhbHVlKSAKCnRtcCAlPiUKICBnZ3Bsb3QoKSArIAogIGdlb21fYm94cGxvdChhZXMoeCA9IGZlei5hdWxhLCB5ID0gdmFsdWUsIGZpbGwgPSBmZXouYXVsYSksIHNob3cubGVnZW5kID0gVCkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEpLCBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsKICBmYWNldF93cmFwKH5pbmRpY2Fkb3IpICsKICB0aGVtZV9idygpICsKICBsYWJzKHRpdGxlID0gIkJveHBsb3QgZGUgaWRlbnRpZmljYcOnw6NvIGRlIGVzcMOpY2llcyBOYXRpdmFzIG5vcyBjcml0w6lyaW9zIGVzdGFiZWxlY2lkb3MgLSBBbHVub3MgcXVlIGZpemVyYW0gYXVsYSIsCiAgICAgICB5ID0gIlBlcmNlbnR1YWwgZGUgaWRlbnRpZmljYcOnw6NvIiwgeCA9ICIiKSArCiAgbXlfdGhlbWUKYGBgCgpgYGB7cn0KYW5vdmFfZmV6LmF1bGEgPC0gdGVzdGUuYW5vdmEoZm9ybXVsYSA9IHZhbHVlIH4gZmV6LmF1bGEsIAogICAgICAgICAgICBkYXRhID0gdG1wICU+JSBmaWx0ZXIoaW5kaWNhZG9yID09ICJpbmRpY2UiKSkKCmFub3ZhX2Zlei5hdWxhJHRlc3RlLm5vcm1hbGlkYWRlCmFub3ZhX2Zlei5hdWxhJHRlc3RlLmFub3ZhCmFub3ZhX2Zlei5hdWxhJHRhYmVsYS50dWtleQpgYGAKCgojIyMgOSAtIEVzdHVkYW50ZXMgZGEgQ2lkYWRlIDEgKGNvbSBVQykgdGVtIG1haW9yIG7Dum1lcm8gZGUgYWNlcnRvcyBkZSBlc3DDqWNpZXMgbmF0aXZhcy4KCmBgYHtyLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD0zfQp0bXAgPC0gCiAgICBwb3NfZ2FiYXJpdG8kcHJvcG9yY29lcyRwb3JfdHVybWFfZmxvbmEgJT4lCiAgICBzZWxlY3QoZmxvbmEsIHBfbm9tZV9uYXRpdmFzID0gcF9uYXRpdmFzLCBwX29yaWdlbV9uYXRpdmFzLCBwX2luZGljZV9uYXRpdmFzKSAlPiUKICAgIGFycmFuZ2UoZmxvbmEpICU+JQogICAgbWVsdChpZCA9ICJmbG9uYSIpCgp0bXAgPC0gY2JpbmQodG1wLCBjb2xzcGxpdCh0bXAkdmFyaWFibGUsICJfIiwgYygicCIsICJpbmRpY2Fkb3IiLCAib3JpZ2VtIikpKSAlPiUKICBzZWxlY3QoZmxvbmEsIGluZGljYWRvciwgb3JpZ2VtLCB2YWx1ZSkgCgp0bXAgJT4lCiAgZ2dwbG90KCkgKyAKICBnZW9tX2JveHBsb3QoYWVzKHggPSBmbG9uYSwgeSA9IHZhbHVlLCBmaWxsID0gZmxvbmEpLCBzaG93LmxlZ2VuZCA9IFQpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwxKSwgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSArCiAgZmFjZXRfd3JhcCh+aW5kaWNhZG9yKSArCiAgdGhlbWVfYncoKSArCiAgbGFicyh0aXRsZSA9ICJCb3hwbG90IGRlIGlkZW50aWZpY2HDp8OjbyBkZSBlc3DDqWNpZXMgTmF0aXZhcyBub3MgY3JpdMOpcmlvcyBlc3RhYmVsZWNpZG9zIC0gQWx1bm9zIHF1ZSB2aXNpdGFyYW0gYSBGbG9uYSIsCiAgICAgICB5ID0gIlBlcmNlbnR1YWwgZGUgaWRlbnRpZmljYcOnw6NvIiwgeCA9ICIiKSArCiAgbXlfdGhlbWUKYGBgCgpgYGB7cn0KYW5vdmFfZmxvbmEgPC0gdGVzdGUuYW5vdmEoZm9ybXVsYSA9IHZhbHVlIH4gZmxvbmEsIAogICAgICAgICAgICBkYXRhID0gdG1wICU+JSBmaWx0ZXIoaW5kaWNhZG9yID09ICJpbmRpY2UiKSkKCmFub3ZhX2Zsb25hJHRlc3RlLm5vcm1hbGlkYWRlCmFub3ZhX2Zsb25hJHRlc3RlLmFub3ZhCmFub3ZhX2Zsb25hJHRhYmVsYS50dWtleQpgYGAKCiMjIyAxMCAtIFJhbmtpbmcgZG9zIGFuaW1haXMKCmBgYHtyLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQphMSA8LSAKICAgIHBvc19nYWJhcml0byRyYWtpbmdfYW5pbWFpcyRuYXRpdm9zICU+JQogICAgaGVhZCgyMCkgJT4lCiAgICBnZ3Bsb3QoYWVzKHggPSBhbmltYWlzLCB5ID0gZnJlcSwgZmlsbCA9IGZyZXEpKSArCiAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIHNob3cubGVnZW5kID0gRikgKwogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGZyZXEpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksIHZqdXN0ID0gLTEsIGhqdXN0ID0gMC41KSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDkwKSkgKwogICAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAib3JhbmdlIiwgaGlnaCA9ICJyZWQiKSArCiAgICB0aGVtZV9idygpICsKICAgIGxhYnModGl0bGUgPSAiRXNww6ljaWVzIGNpdGFkYXMgY29tbyBuYXRpdmFzIiwKICAgICAgIHkgPSAiRnJlcXVlbmNpYSIsIHggPSAiIikgKwogICAgbXlfdGhlbWUKYTIgPC0gCiAgICBwb3NfZ2FiYXJpdG8kcmFraW5nX2FuaW1haXMkZXhvdGljb3MgJT4lCiAgICBoZWFkKDIwKSAlPiUKICAgIGdncGxvdChhZXMoeCA9IGFuaW1haXMsIHkgPSBmcmVxLCBmaWxsID0gZnJlcSkpICsKICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iiwgc2hvdy5sZWdlbmQgPSBGKSArCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gZnJlcSksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSwgdmp1c3QgPSAtMSwgaGp1c3QgPSAwLjUpICsKICAgIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsOTApKSArCiAgICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJsaWdodGJsdWUiLCBoaWdoID0gImRhcmtibHVlIikgKwogICAgdGhlbWVfYncoKSArCiAgICBsYWJzKHRpdGxlID0gIkVzcMOpY2llcyBjaXRhZGFzIGNvbW8gZXjDs3RpY2FzIiwKICAgICAgIHkgPSAiRnJlcXVlbmNpYSIsIHggPSAiIikgKwogICAgbXlfdGhlbWUKCmdyaWQuYXJyYW5nZShhMSwgYTIsCiAgICAgICAgICAgICBucm93ID0gMiwKICAgICAgICAgICAgIHRvcCA9IHRleHRHcm9iKCJUT1AgMjAgLSBSYW5raW5nIGRhcyBlc3DDqWNpZXMgY2l0YWRhcyBjb21vIGV4ZW1wbG9cbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3AgPSBncGFyKGZvbnRzaXplID0gMjAsIGZvbnQgPSAyKSkKKQpgYGAKCiMjIyAxMSAtIFJhbmtpbmcgZG9zIGFuaW1haXMgY2l0YWRvcyBwYXJhIHByb3Rlw6fDo28KCmBgYHtyLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD0yfQphMyA8LSAKICAgIHBvc19nYWJhcml0byRyYWtpbmdfYW5pbWFpcyRwcm90ZWdpZG9zICU+JQogICAgaGVhZCgyMCkgJT4lCiAgICBnZ3Bsb3QoYWVzKHggPSBhbmltYWlzLCB5ID0gZnJlcSwgZmlsbCA9IGZyZXEpKSArCiAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIHNob3cubGVnZW5kID0gRikgKwogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGZyZXEpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksIHZqdXN0ID0gLTEsIGhqdXN0ID0gMC41KSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDE5MCkpICsKICAgIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gImdyZWVuIiwgaGlnaCA9ICJkYXJrZ3JlZW4iKSArCiAgICB0aGVtZV9idygpICsKICAgIGxhYnModGl0bGUgPSAiRXNww6ljaWVzIGNpdGFkYXMgY29tbyBuYXRpdmFzIiwKICAgICAgIHkgPSAiRnJlcXVlbmNpYSIsIHggPSAiIikgKwogICAgbXlfdGhlbWUKCmdyaWQuYXJyYW5nZShhMywKICAgICAgICAgICAgIHRvcCA9IHRleHRHcm9iKCJUT1AgMjAgLSBSYW5raW5nIGRhcyBlc3DDqWNpZXMgY2l0YWRhcyBjb21vIGV4ZW1wbG8gcGFyYSBwcm90ZcOnw6NvXG4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdwID0gZ3Bhcihmb250c2l6ZSA9IDIwLCBmb250ID0gMikpCikKYGBgCgpgYGB7ciwgZWNobz1GQUxTRX0KIyMgQW5vdmEgcG9yIGdydXBvIGRlIGVzcMOpY2llcwoKIyBmb3IoZ3JwIGluIHVuaXF1ZShwb3NfZ2FiYXJpdG8kZXNwZWNpZSRncnVwbykpIHsKIyAgICAgbWVzc2FnZShncnApCiMgICAgIAojICAgICBUdWtleUhTRChhb3YobG0oYWNlcnRvcyB+IGVzcGVjaWUgKyBncnVwbywgdGJsX2VzcGVjaWVzMSkpKQojICAgICBkYWRvcyA8LSAKIyAgICAgICAgIHBvc19nYWJhcml0byRlc3BlY2llc0JydXRvICU+JSAKIyAgICAgICAgIGZpbHRlcihncnVwbyA9PSBncnApICU+JSAKIyAgICAgICAgIG11dGF0ZSh2YWx1ZSA9IGZyLCBlc3BlY2llID0gZmFjdG9yKGVzcGVjaWUpKQojICAgICAjcHJpbnQoZGFkb3MpCiMgICAgICNhZ2dyZWdhdGUodmFsdWUgfiBncnVwbywgZGFkb3MsICBGVU4gPSBmdW5jdGlvbih4KSBzaGFwaXJvLnRlc3QoeCkkcC52YWx1ZSkKIyAgICAgCiMgICAgIHNoYXBpcm8udGVzdChkYWRvcyRmcikKIyAgICAgYW5vdmEobG0oZnIgfiBlc3BlY2llLCBkYWRvcykpCiMgICAgIFR1a2V5SFNEKGFvdihsbShmciB+IGVzcGVjaWUsIGRhZG9zKSkpCiMgfQpgYGAKCg==